ZQuest Classic Coverage Report


Directory: src/
File: src/zc/maps.cpp
Date: 2025-11-21 07:35:34
Exec Total Coverage
Lines: 4199 5226 80.3%
Functions: 294 332 88.6%
Branches: 3247 5300 61.3%

Line Branch Exec Source
1 #include "base/combo.h"
2 #include "base/handles.h"
3 #include "base/util.h"
4 #include "base/zdefs.h"
5 #include "base/general.h"
6 #include <cstring>
7 #include <assert.h>
8 #include <math.h>
9 #include <vector>
10 #include <deque>
11 #include <string>
12 #include <set>
13 #include <array>
14 #include <sstream>
15 using std::set;
16
17 #include "base/qrs.h"
18 #include "base/dmap.h"
19 #include "base/mapscr.h"
20 #include "base/misctypes.h"
21 #include "base/initdata.h"
22 #include "zc/maps.h"
23 #include "zc/zelda.h"
24 #include "zc/zc_ffc.h"
25 #include "tiles.h"
26 #include "sprite.h"
27 #include "gui/jwin.h"
28 #include "base/zsys.h"
29 #include "subscr.h"
30 #include "zc/zc_subscr.h"
31 #include "zc/hero.h"
32 #include "zc/guys.h"
33 #include "zc/ffscript.h"
34 #include "drawing.h"
35 #include "zc/combos.h"
36 #include "zc/replay.h"
37 #include "slopes.h"
38 #include "particles.h"
39 #include <fmt/format.h>
40 #include "zc/render.h"
41 #include "iter.h"
42 #include <ranges>
43
44 // All the temporary screens (and their layers) for the currently loaded map.
45 static mapscr* temporary_screens[136*7];
46 // Set by load_region.
47 static bool screen_in_current_region[136];
48 427 static rpos_handle_t current_region_rpos_handles[136*7];
49 static bool current_region_rpos_handles_dirty;
50 static int current_region_screen_count;
51 static std::pair<const rpos_handle_t*, int> current_region_rpos_handles_scr[136];
52
53 viewport_t viewport;
54 static int viewport_sprite_uid;
55 ViewportMode viewport_mode;
56 int world_w, world_h;
57 int region_scr_dx, region_scr_dy;
58 int region_scr_count;
59 rpos_t region_max_rpos;
60 int region_num_rpos;
61 region_t cur_region, scrolling_region;
62
63 427 maze_state_t maze_state;
64 int scrolling_maze_last_solved_screen;
65
66 608 void maps_init_game_vars()
67 {
68 608 viewport = {};
69 608 viewport_mode = ViewportMode::CenterAndBound;
70 608 viewport_sprite_uid = 1;
71 608 currscr_for_passive_subscr = -1;
72 608 }
73
74 static region_ids_t current_region_ids;
75
76 // Returns true if the (map, screen) is inside a scrolling region.
77 15148685 static bool is_in_scrolling_region(int map, int screen)
78 {
79 15148685 return get_region_id(map, screen) != 0;
80 }
81
82 bool is_in_screenscrolling_region(int screen)
83 {
84 if (!screenscrolling) return false;
85
86 int x = screen % 16;
87 int y = screen / 16;
88 return
89 scrolling_region.origin_screen_x >= x && scrolling_region.origin_screen_x < x + scrolling_region.screen_width &&
90 scrolling_region.origin_screen_y >= y && scrolling_region.origin_screen_y < y + scrolling_region.screen_height;
91 }
92
93 9004506513 bool is_in_scrolling_region()
94 {
95 9004506513 return cur_region.screen_count > 1;
96 }
97
98 2232 static bool is_same_region_id(int region_origin_scr, int map, int scr)
99 {
100
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 1460 times.
2232 if (!is_in_scrolling_region(map, scr)) return false;
101 1460 int region_id = get_region_id(map, region_origin_scr);
102
1/2
✓ Branch 0 taken 1460 times.
✗ Branch 1 not taken.
1460 return region_id && region_id == get_region_id(map, scr);
103 2232 }
104
105 251433069 bool is_in_current_region(int map, int screen)
106 {
107
2/2
✓ Branch 0 taken 1598 times.
✓ Branch 1 taken 251431471 times.
251433069 if (map != cur_map)
108 1598 return false;
109
110
3/4
✓ Branch 0 taken 251431471 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 251419258 times.
✓ Branch 3 taken 12213 times.
251431471 if (screen >= 0 && screen < 128)
111 251419258 return screen_in_current_region[screen];
112
113 12213 return screen == cur_screen;
114 251433069 }
115
116 244743880 bool is_in_current_region(int screen)
117 {
118
5/6
✓ Branch 0 taken 243628262 times.
✓ Branch 1 taken 1115618 times.
✓ Branch 2 taken 1115618 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1115613 times.
244743880 return screen == cur_screen || (screen >= 0 && screen < 128 && screen_in_current_region[screen]);
119 }
120
121 30774063 bool is_in_current_region(mapscr* scr)
122 {
123
2/2
✓ Branch 0 taken 14690 times.
✓ Branch 1 taken 30759373 times.
30774063 return scr->map == cur_map && is_in_current_region(scr->screen);
124 }
125
126 63791987 bool is_extended_height_mode()
127 {
128
2/2
✓ Branch 0 taken 63592539 times.
✓ Branch 1 taken 199448 times.
63791987 return cur_region.screen_height > 1 && (DMaps[cur_dmap].flags & dmfEXTENDEDVIEWPORT);
129 }
130
131 // Returns 0 if this is not a scrolling region.
132 42487477 int get_region_id(int map, int screen)
133 {
134
2/2
✓ Branch 0 taken 401435 times.
✓ Branch 1 taken 42086042 times.
42487477 if (screen >= 128) return 0;
135
2/2
✓ Branch 0 taken 42084918 times.
✓ Branch 1 taken 1124 times.
42086042 if (map == cur_region.map) return current_region_ids[screen];
136
137 1124 return Regions[map].get_region_id(screen);
138 42487477 }
139
140 27276802 int get_current_region_id()
141 {
142 27276802 return get_region_id(cur_map, cur_screen);
143 }
144
145 67244 void calculate_region(int map, int screen, region_t& region, int& region_scr_dx, int& region_scr_dy)
146 {
147 67244 region.map = map;
148
149
2/2
✓ Branch 0 taken 66970 times.
✓ Branch 1 taken 274 times.
67244 if (!is_in_scrolling_region(map, screen))
150 {
151 66970 region.region_id = 0;
152 66970 region.origin_screen = screen;
153 66970 region.origin_screen_x = screen % 16;
154 66970 region.origin_screen_y = screen / 16;
155 66970 region.screen_width = 1;
156 66970 region.screen_height = 1;
157 66970 region.screen_count = 1;
158 66970 region.width = 256;
159 66970 region.height = 176;
160 66970 region_scr_dx = 0;
161 66970 region_scr_dy = 0;
162 66970 return;
163 }
164
165 274 int input_scr_x = screen % 16;
166 274 int input_scr_y = screen / 16;
167
168 // For the given screen, find the top-left corner of its region.
169 274 int origin_scr_x = input_scr_x;
170 274 int origin_scr_y = input_scr_y;
171 274 int origin_scr = screen;
172
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 372 times.
434 while (origin_scr_x > 0)
173 {
174
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 160 times.
372 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x - 1, origin_scr_y))) break;
175 160 origin_scr_x--;
176 }
177
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 414 times.
508 while (origin_scr_y > 0)
178 {
179
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 234 times.
414 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, origin_scr_y - 1))) break;
180 234 origin_scr_y--;
181 }
182 274 origin_scr = map_scr_xy_to_index(origin_scr_x, origin_scr_y);
183
184 // Now find the bottom-right corner.
185 274 int region_scr_right = origin_scr_x;
186
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 614 times.
642 while (region_scr_right < 15)
187 {
188
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 368 times.
614 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(region_scr_right + 1, origin_scr_y))) break;
189 368 region_scr_right++;
190 }
191 274 int region_scr_bottom = origin_scr_y;
192
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 832 times.
856 while (region_scr_bottom < 7)
193 {
194
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 582 times.
832 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, region_scr_bottom + 1))) break;
195 582 region_scr_bottom++;
196 }
197
198 274 region.region_id = get_region_id(map, origin_scr);
199 274 region.origin_screen = origin_scr;
200 274 region.origin_screen_x = origin_scr_x;
201 274 region.origin_screen_y = origin_scr_y;
202 274 region.screen_width = region_scr_right - origin_scr_x + 1;
203 274 region.screen_height = region_scr_bottom - origin_scr_y + 1;
204 274 region.screen_count = region.screen_width * region.screen_height;
205 274 region.width = 256 * region.screen_width;
206 274 region.height = 176 * region.screen_height;
207 274 region_scr_dx = input_scr_x - origin_scr_x;
208 274 region_scr_dy = input_scr_y - origin_scr_y;
209
210 DCHECK_RANGE_INCLUSIVE(region.screen_width, 0, 16);
211 DCHECK_RANGE_INCLUSIVE(region.screen_height, 0, 8);
212 67244 }
213
214 37530 void load_region(int dmap, int screen)
215 {
216 37530 clear_temporary_screens();
217
218 37530 int map = DMaps[dmap].map;
219 37530 current_region_ids = Regions[map].get_all_region_ids();
220
221 37530 calculate_region(map, screen, cur_region, region_scr_dx, region_scr_dy);
222 37530 cur_screen = cur_region.origin_screen;
223 37530 world_w = cur_region.width;
224 37530 world_h = cur_region.height;
225 37530 region_scr_count = cur_region.screen_count;
226 37530 region_max_rpos = (rpos_t)(cur_region.screen_count*176 - 1);
227 37530 region_num_rpos = cur_region.screen_count*176;
228 37530 scrolling_maze_last_solved_screen = 0;
229
230 37530 memset(screen_in_current_region, false, sizeof(screen_in_current_region));
231
2/2
✓ Branch 0 taken 37764 times.
✓ Branch 1 taken 37530 times.
75294 for (int x = 0; x < cur_region.screen_width; x++)
232 {
233
2/2
✓ Branch 0 taken 38774 times.
✓ Branch 1 taken 37764 times.
76538 for (int y = 0; y < cur_region.screen_height; y++)
234 {
235 38774 int screen = cur_screen + x + y*16;
236
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38774 times.
38774 if (screen < 136)
237 {
238 38774 screen_in_current_region[screen] = true;
239 38774 }
240 38774 }
241 37764 }
242
243 37530 mark_current_region_handles_dirty();
244 37530 }
245
246 37530 static void prepare_current_region_handles()
247 {
248 37530 current_region_rpos_handles_dirty = false;
249 37530 current_region_screen_count = 0;
250
2/2
✓ Branch 0 taken 37878 times.
✓ Branch 1 taken 37530 times.
75408 for (int y = 0; y < cur_region.screen_height; y++)
251 {
252
2/2
✓ Branch 0 taken 38774 times.
✓ Branch 1 taken 37878 times.
76652 for (int x = 0; x < cur_region.screen_width; x++)
253 {
254 38774 int screen = cur_screen + x + y*16;
255 38774 int index_start = current_region_screen_count;
256
2/2
✓ Branch 0 taken 38774 times.
✓ Branch 1 taken 271418 times.
310192 for (int layer = 0; layer <= 6; layer++)
257 {
258 271418 mapscr* scr = get_scr_layer(screen, layer);
259
2/2
✓ Branch 0 taken 95243 times.
✓ Branch 1 taken 176175 times.
271418 if (!scr->is_valid())
260 {
261
1/2
✓ Branch 0 taken 176175 times.
✗ Branch 1 not taken.
176175 if (layer == 0) break;
262 176175 continue;
263 }
264
265 95243 rpos_t base_rpos = POS_TO_RPOS(0, get_region_relative_dx(screen), get_region_relative_dy(screen));
266 95243 current_region_rpos_handles[current_region_screen_count] = {scr, screen, layer, base_rpos, 0};
267 95243 current_region_screen_count += 1;
268 95243 }
269
270 38774 int num_handles_for_scr = current_region_screen_count - index_start;
271 38774 current_region_rpos_handles_scr[screen] = {&current_region_rpos_handles[index_start], num_handles_for_scr};
272 38774 }
273 37878 }
274 37530 }
275
276 1735212928 std::tuple<const rpos_handle_t*, int> get_current_region_handles()
277 {
278 DCHECK(!current_region_rpos_handles_dirty);
279 1735212928 return {current_region_rpos_handles, current_region_screen_count};
280 }
281
282 11484384 std::tuple<const rpos_handle_t*, int> get_current_region_handles(mapscr* scr)
283 {
284 DCHECK(!current_region_rpos_handles_dirty);
285
2/4
✓ Branch 0 taken 11484384 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11484384 times.
11484384 if (scr == special_warp_return_scr || current_region_rpos_handles_dirty)
286 return {nullptr, 0};
287
288
2/2
✓ Branch 0 taken 65877 times.
✓ Branch 1 taken 11418507 times.
11484384 if (cur_screen >= 0x80)
289 {
290 DCHECK(scr == origin_scr);
291 65877 return {nullptr, 0};
292 }
293
294 DCHECK(is_in_current_region(scr));
295 11418507 return current_region_rpos_handles_scr[scr->screen];
296 11484384 }
297
298 37530 void mark_current_region_handles_dirty()
299 {
300 37530 current_region_rpos_handles_dirty = true;
301 37530 }
302
303 68003 void delete_temporary_screens(mapscr** screens)
304 {
305
2/2
✓ Branch 0 taken 64738856 times.
✓ Branch 1 taken 68003 times.
64806859 for (int i = 0; i < 136*7; i++)
306 {
307
2/2
✓ Branch 0 taken 267351 times.
✓ Branch 1 taken 64471505 times.
64738856 if (!screens[i])
308 64471505 continue;
309
310 267351 mapscr* scr = screens[i];
311 267351 int num_ffcs = scr->numFFC();
312
2/2
✓ Branch 0 taken 7621503 times.
✓ Branch 1 taken 267351 times.
7888854 for (int i = 0; i < num_ffcs; i++)
313 {
314 7621503 sprite* ffc = &scr->ffcs[i];
315
2/2
✓ Branch 0 taken 7617968 times.
✓ Branch 1 taken 3535 times.
7621503 if (ffc->uid)
316 3535 FFCore.release_sprite_owned_objects(ffc->uid);
317 7621503 }
318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 267351 times.
267351 delete scr;
319 267351 screens[i] = NULL;
320 267351 }
321 68003 }
322
323 38700 void clear_temporary_screens()
324 {
325 38700 delete_temporary_screens(temporary_screens);
326 38700 origin_scr = nullptr;
327 38700 hero_scr = nullptr;
328 38700 }
329
330 29307 std::vector<mapscr*> take_temporary_scrs()
331 {
332
1/2
✓ Branch 0 taken 29307 times.
✗ Branch 1 not taken.
29307 std::vector<mapscr*> screens(temporary_screens, temporary_screens + 136*7);
333
2/2
✓ Branch 0 taken 29307 times.
✓ Branch 1 taken 27900264 times.
27929571 for (int i = 0; i < 136*7; i++)
334 27900264 temporary_screens[i] = nullptr;
335
336 29307 return screens;
337
1/2
✓ Branch 0 taken 29307 times.
✗ Branch 1 not taken.
29307 }
338
339 15079569 void calculate_viewport(viewport_t& viewport, int dmap, int screen, int world_w, int world_h, int x, int y)
340 {
341 // TODO: In future, maybe add x/y centering offsets to zscript (Viewport->TargetXOffset/Viewport->TargetYOffset).
342
343
2/2
✓ Branch 0 taken 15032987 times.
✓ Branch 1 taken 46582 times.
15079569 bool extended_height_mode = (DMaps[dmap].flags & dmfEXTENDEDVIEWPORT) && world_h > 176;
344 15079569 viewport.w = 256;
345 15079569 viewport.h = 176 + (extended_height_mode ? 56 : 0);
346
347
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 15079209 times.
15079569 if (viewport_mode == ViewportMode::Script)
348 360 return;
349
350
2/2
✓ Branch 0 taken 46162 times.
✓ Branch 1 taken 15033047 times.
15079209 if (!is_in_scrolling_region(DMaps[dmap].map, screen))
351 {
352 15033047 viewport.x = 0;
353 15033047 viewport.y = 0;
354 15033047 }
355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46162 times.
46162 else if (viewport_mode == ViewportMode::CenterAndBound)
356 {
357 // Clamp the viewport to the edges of the region.
358
6/6
✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 37594 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 39374 times.
✓ Branch 4 taken 8568 times.
✓ Branch 5 taken 30806 times.
46162 viewport.x = CLAMP(0, world_w - viewport.w, x - viewport.w/2);
359
6/6
✓ Branch 0 taken 11856 times.
✓ Branch 1 taken 34306 times.
✓ Branch 2 taken 5650 times.
✓ Branch 3 taken 40512 times.
✓ Branch 4 taken 11856 times.
✓ Branch 5 taken 28656 times.
46162 viewport.y = CLAMP(0, world_h - viewport.h, y - viewport.h/2);
360 46162 }
361 else if (viewport_mode == ViewportMode::Center)
362 {
363 viewport.x = x - viewport.w/2;
364 viewport.y = y - viewport.h/2;
365 }
366 15079569 }
367
368 15079058 sprite* get_viewport_sprite()
369 {
370 15079058 sprite* spr = sprite::getByUID(viewport_sprite_uid);
371
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 15079052 times.
15079058 if (!spr)
372 {
373 6 viewport_sprite_uid = 1; // Hero uid.
374 6 spr = &Hero;
375 6 }
376
377 15079058 return spr;
378 }
379
380 6 void set_viewport_sprite(sprite* spr)
381 {
382 6 viewport_sprite_uid = spr->uid;
383 6 }
384
385 15049751 void update_viewport()
386 {
387 15049751 sprite* spr = get_viewport_sprite();
388 15049751 int x = spr->x + spr->txsz*16/2;
389 15049751 int y = spr->y + spr->tysz*16/2;
390 15049751 calculate_viewport(viewport, cur_dmap, cur_screen, world_w, world_h, x, y);
391 15049751 }
392
393 // TODO: should add a moveflag to sprites to configure the size of this rect (or effectively disable
394 // freezing if the rect returns is large enough). See:
395 // https://discord.com/channels/876899628556091432/1358483603700449581
396 // https://discord.com/channels/876899628556091432/1130384911983980554
397 //
398 89034484 viewport_t get_sprite_freeze_rect()
399 {
400 89034484 viewport_t freeze_rect = viewport;
401 89034484 int tile_buffer = 3;
402 89034484 freeze_rect.w += 16 * tile_buffer * 2;
403 89034484 freeze_rect.h += 16 * tile_buffer * 2;
404 89034484 freeze_rect.x -= 16 * tile_buffer;
405 89034484 freeze_rect.y -= 16 * tile_buffer;
406 89034484 return freeze_rect;
407 }
408
409 4722 mapscr* determine_hero_screen_from_coords()
410 {
411 4722 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
412 4722 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
413 4722 int dx = x / 256;
414 4722 int dy = y / 176;
415 4722 return get_scr(cur_screen + dx + dy * 16);
416 }
417
418 28218 bool edge_of_region(direction dir)
419 {
420
2/2
✓ Branch 0 taken 28138 times.
✓ Branch 1 taken 80 times.
28218 if (!is_in_scrolling_region()) return true;
421
422 80 int screen_x = Hero.current_screen % 16;
423 80 int screen_y = Hero.current_screen / 16;
424
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if (dir == up) screen_y -= 1;
425
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 10 times.
80 if (dir == down) screen_y += 1;
426
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 30 times.
80 if (dir == left) screen_x -= 1;
427
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 38 times.
80 if (dir == right) screen_x += 1;
428
4/8
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
80 if (screen_x < 0 || screen_x > 16 || screen_y < 0 || screen_y > 8) return true;
429 80 return !is_in_current_region(map_scr_xy_to_index(screen_x, screen_y));
430 28218 }
431
432 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
433 // Coordinates are clamped to the world bounds.
434 338104866 int get_screen_for_world_xy(int x, int y)
435 {
436
2/2
✓ Branch 0 taken 316965842 times.
✓ Branch 1 taken 21139024 times.
338104866 if (!is_in_scrolling_region())
437 316965842 return cur_screen;
438
439 21139024 int dx = std::clamp(x, 0, world_w - 1) / 256;
440 21139024 int dy = std::clamp(y, 0, world_h - 1) / 176;
441 21139024 int origin_screen_x = cur_screen % 16;
442 21139024 int origin_screen_y = cur_screen / 16;
443 21139024 int scr_x = origin_screen_x + dx;
444 21139024 int scr_y = origin_screen_y + dy;
445 21139024 return map_scr_xy_to_index(scr_x, scr_y);
446 338104866 }
447
448 31102071 int get_screen_for_rpos(rpos_t rpos)
449 {
450 31102071 int origin_screen_x = cur_screen % 16;
451 31102071 int origin_screen_y = cur_screen / 16;
452 31102071 int screen = static_cast<int32_t>(rpos) / 176;
453 31102071 int scr_x = origin_screen_x + screen%cur_region.screen_width;
454 31102071 int scr_y = origin_screen_y + screen/cur_region.screen_width;
455 31102071 return map_scr_xy_to_index(scr_x, scr_y);
456 }
457
458 837273888 rpos_handle_t get_rpos_handle(rpos_t rpos, int layer)
459 {
460 DCHECK_LAYER_ZERO_INDEX(layer);
461
2/2
✓ Branch 0 taken 806309780 times.
✓ Branch 1 taken 30964108 times.
837273888 if (!is_in_scrolling_region())
462 806309780 return {get_scr_layer(cur_screen, layer), cur_screen, layer, rpos, RPOS_TO_POS(rpos)};
463 30964108 int screen = get_screen_for_rpos(rpos);
464 30964108 mapscr* scr = get_scr_layer(screen, layer);
465 30964108 return {scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
466 837273888 }
467
468 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
469 // Coordinates are clamped to the world bounds.
470 3485337825 rpos_handle_t get_rpos_handle_for_world_xy(int x, int y, int layer)
471 {
472 3485337825 x = std::clamp(x, 0, world_w - 1);
473 3485337825 y = std::clamp(y, 0, world_h - 1);
474
475 DCHECK_LAYER_ZERO_INDEX(layer);
476
2/2
✓ Branch 0 taken 3458995347 times.
✓ Branch 1 taken 26342478 times.
3485337825 if (!is_in_scrolling_region())
477 {
478 3458995347 int pos = COMBOPOS(x, y);
479 3458995347 return {get_scr_layer(cur_screen, layer), cur_screen, layer, (rpos_t)pos, pos};
480 }
481 26342478 return get_rpos_handle(COMBOPOS_REGION(x, y), layer);
482 3485337825 }
483
484 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
485 1926 rpos_handle_t get_rpos_handle_for_screen(int screen, int layer, int pos)
486 {
487 DCHECK_LAYER_ZERO_INDEX(layer);
488 1926 return {get_scr_layer(screen, layer), screen, layer, POS_TO_RPOS(pos, screen), pos};
489 }
490
491 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
492 // Use this instead of the other `get_pos_handle_for_screen` if you already have a reference to the screen.
493 63140 rpos_handle_t get_rpos_handle_for_scr(mapscr* scr, int layer, int pos)
494 {
495 DCHECK_LAYER_ZERO_INDEX(layer);
496 63140 return {scr, scr->screen, layer, POS_TO_RPOS(pos, scr->screen), pos};
497 }
498
499 25594487 void change_rpos_handle_layer(rpos_handle_t& rpos_handle, int layer)
500 {
501 DCHECK_LAYER_ZERO_INDEX(layer);
502 25594487 rpos_handle.layer = layer;
503 25594487 rpos_handle.scr = get_scr_layer(rpos_handle.screen, layer);
504 25594487 }
505
506 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
507 // Coordinates are clamped to the world bounds.
508 86712 combined_handle_t get_combined_handle_for_world_xy(int x, int y, int layer)
509 {
510 DCHECK_LAYER_ZERO_INDEX(layer);
511
512 86712 x = std::clamp(x, 0, world_w - 1);
513 86712 y = std::clamp(y, 0, world_h - 1);
514
515 86712 auto maybe_ffc_handle = getFFCAt(x, y);
516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86712 times.
86712 if (maybe_ffc_handle)
517 return maybe_ffc_handle.value();
518
519 86712 auto rpos = COMBOPOS_REGION_B(x, y);
520
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86712 times.
86712 if (rpos == rpos_t::None)
521 return rpos_handle_t();
522 86712 return get_rpos_handle(rpos, layer);
523 86712 }
524
525 // These functions all return _temporary_ screens. Any modifications made to them (either by the engine
526 // directly or via zscript) only last until the next area is loaded (via loadscr).
527
528 // Returns the screen containing the (x, y) world position.
529 1555282398 mapscr* get_scr_for_world_xy(int x, int y)
530 {
531 // Quick path, but should work the same without.
532
2/2
✓ Branch 0 taken 1544842998 times.
✓ Branch 1 taken 10439400 times.
1555282398 if (!is_in_scrolling_region()) return origin_scr;
533 10439400 return get_scr(get_screen_for_world_xy(x, y));
534 1555282398 }
535
536 26000778 mapscr* get_scr_for_rpos(rpos_t rpos)
537 {
538 // Quick path, but should work the same without.
539
2/2
✓ Branch 0 taken 25862832 times.
✓ Branch 1 taken 137946 times.
26000778 if (!is_in_scrolling_region()) return origin_scr;
540 137946 return get_scr(get_screen_for_rpos(rpos));
541 26000778 }
542
543 17 mapscr* get_scr_for_rpos_layer(rpos_t rpos, int layer)
544 {
545 17 return get_scr_layer(get_screen_for_rpos(rpos), layer);
546 }
547
548 // Note: layer=0 is the base screen, 1 is the first layer, etc.
549 2135612379 mapscr* get_scr_for_world_xy_layer(int x, int y, int layer)
550 {
551 DCHECK_LAYER_ZERO_INDEX(layer);
552
2/2
✓ Branch 0 taken 2125567165 times.
✓ Branch 1 taken 10045214 times.
2135612379 if (!is_in_scrolling_region()) return get_scr_layer(cur_screen, layer);
553
2/2
✓ Branch 0 taken 708934 times.
✓ Branch 1 taken 9336280 times.
10045214 return layer == 0 ?
554 708934 get_scr_for_world_xy(x, y) :
555 9336280 get_scr_layer(get_screen_for_world_xy(x, y), layer);
556 2135612379 }
557
558 1748698028 int get_region_screen_offset(int screen)
559 {
560 1748698028 return get_region_relative_dx(screen) + get_region_relative_dy(screen) * cur_region.screen_width;
561 }
562
563 655240230 int get_screen_for_region_index_offset(int offset)
564 {
565 655240230 int scr_dx = offset % cur_region.screen_width;
566 655240230 int scr_dy = offset / cur_region.screen_width;
567 655240230 int screen = cur_screen + scr_dx + scr_dy*16;
568 655240230 return screen;
569 }
570
571 655056392 mapscr* get_scr_for_region_index_offset(int offset)
572 {
573 655056392 int screen = get_screen_for_region_index_offset(offset);
574 655056392 return get_scr(screen);
575 }
576
577 // The screen at (map, screen) must exist.
578 1540989990 mapscr* get_scr(int map, int screen)
579 {
580 1540989990 mapscr* scr = get_scr_maybe(map, screen);
581
1/2
✓ Branch 0 taken 1540989990 times.
✗ Branch 1 not taken.
1540989990 CHECK(scr);
582 1540989990 return scr;
583 }
584
585 841466847 mapscr* get_scr(int screen)
586 {
587 841466847 return get_scr(cur_map, screen);
588 }
589
590 // Returns null if active screen does not exist.
591 1726838176 mapscr* get_scr_maybe(int map, int screen)
592 {
593 DCHECK_RANGE_INCLUSIVE(screen, 0, 135);
594
595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1726838176 times.
1726838176 if (map == cur_map)
596 {
597
2/2
✓ Branch 0 taken 1706012202 times.
✓ Branch 1 taken 20825974 times.
1726838176 if (screen == cur_screen)
598 1706012202 return origin_scr;
599
600 20825974 int index = screen*7;
601
2/2
✓ Branch 0 taken 20802272 times.
✓ Branch 1 taken 23702 times.
20825974 if (temporary_screens[index])
602 20802272 return temporary_screens[index];
603
604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23702 times.
23702 if (screen == home_screen)
605 return special_warp_return_scr;
606 23702 }
607
608
4/6
✓ Branch 0 taken 23700 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 23700 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 23700 times.
23702 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
609 {
610 23700 int index = screen*7;
611
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23700 times.
23700 if (FFCore.ScrollingScreensAll[index])
612 23700 return FFCore.ScrollingScreensAll[index];
613 }
614
615 2 return nullptr;
616 1726838176 }
617
618 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
619 6987432569 mapscr* get_scr_layer(int map, int screen, int layer)
620 {
621 DCHECK_LAYER_ZERO_INDEX(layer);
622
2/2
✓ Branch 0 taken 6290848042 times.
✓ Branch 1 taken 696584527 times.
6987432569 if (layer == 0)
623 696584527 return get_scr(map, screen);
624
625
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6290848042 times.
6290848042 if (map == cur_map)
626 {
627 6290848042 int index = screen*7 + layer;
628
2/2
✓ Branch 0 taken 6290703982 times.
✓ Branch 1 taken 144060 times.
6290848042 if (temporary_screens[index])
629 6290703982 return temporary_screens[index];
630
631
2/2
✓ Branch 0 taken 1860 times.
✓ Branch 1 taken 142200 times.
144060 if (screen == home_screen)
632 1860 return &special_warp_return_scrs[layer];
633 142200 }
634
635
1/2
✓ Branch 0 taken 142200 times.
✗ Branch 1 not taken.
142200 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
636 {
637 142200 int index = screen*7 + layer;
638
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142200 times.
142200 if (FFCore.ScrollingScreensAll[index])
639 142200 return FFCore.ScrollingScreensAll[index];
640 }
641
642 NOTREACHED();
643 6987432569 }
644
645 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
646 6565293709 mapscr* get_scr_layer(int screen, int layer)
647 {
648 6565293709 return get_scr_layer(cur_map, screen, layer);
649 }
650
651 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
652 // Return nullptr if screen is not valid.
653 419158503 mapscr* get_scr_layer_valid(int screen, int layer)
654 {
655
2/2
✓ Branch 0 taken 98840427 times.
✓ Branch 1 taken 320318076 times.
419158503 if (mapscr* scr = get_scr_layer(cur_map, screen, layer); scr->is_valid())
656 98840427 return scr;
657 320318076 return nullptr;
658 419158503 }
659
660 401 mapscr* get_scr_current_region_dir(int screen, direction dir)
661 {
662 401 int x = get_region_relative_dx(screen);
663 401 int y = get_region_relative_dy(screen);
664
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
401 if (dir == left && x == 0)
665 71 return nullptr;
666
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
330 if (dir == right && x == 15)
667 return nullptr;
668
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
330 if (dir == down && y == 7)
669 return nullptr;
670
3/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
330 if (dir == up && y == 0)
671 189 return nullptr;
672
673 141 screen = screen_index_direction(screen, dir);
674
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (is_in_current_region(screen))
675 return get_scr(screen);
676
677 141 return nullptr;
678 401 }
679
680 183838 ffc_handle_t get_ffc_handle(ffc_id_t id)
681 {
682 183838 uint8_t screen = get_screen_for_region_index_offset(id / MAXFFCS);
683 183838 uint8_t i = id % MAXFFCS;
684 183838 mapscr* scr = get_scr(screen);
685 183838 ffcdata* ffc = &scr->getFFC(id % MAXFFCS);
686 183838 return {scr, screen, id, i, ffc};
687 }
688
689 34571 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen, int x, int y)
690 {
691 34571 x += get_region_relative_dx(screen) * 256;
692 34571 y += get_region_relative_dy(screen) * 176;
693 34571 return {x, y};
694 }
695
696 1056043 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen)
697 {
698 1056043 int x = get_region_relative_dx(screen) * 256;
699 1056043 int y = get_region_relative_dy(screen) * 176;
700 1056043 return {x, y};
701 }
702
703 12690697673 int32_t COMBOPOS(int32_t x, int32_t y)
704 {
705 DCHECK(x >= 0 && x < 256 && y >= 0 && y < 176);
706 12690697673 return (y & 0xF0) + (x >> 4);
707 }
708 int32_t COMBOPOS_B(int32_t x, int32_t y)
709 {
710 if(unsigned(x) >= 256 || unsigned(y) >= 176)
711 return -1;
712 return (y & 0xF0) + (x >> 4);
713 }
714 3953286650 int32_t COMBOX(int32_t pos)
715 {
716 3953286650 return pos % 16 * 16;
717 }
718 3953286650 int32_t COMBOY(int32_t pos)
719 {
720 3953286650 return pos & 0xF0;
721 }
722
723 116980125 rpos_t COMBOPOS_REGION(int32_t x, int32_t y)
724 {
725
2/2
✓ Branch 0 taken 89822173 times.
✓ Branch 1 taken 27157952 times.
116980125 if (!is_in_scrolling_region())
726 89822173 return (rpos_t) COMBOPOS(x, y);
727
728 DCHECK(is_in_world_bounds(x, y));
729 27157952 int scr_dx = x / (16*16);
730 27157952 int scr_dy = y / (11*16);
731 27157952 int pos = COMBOPOS(x%256, y%176);
732 27157952 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
733 116980125 }
734 6959454095 rpos_t COMBOPOS_REGION_B(int32_t x, int32_t y)
735 {
736
2/2
✓ Branch 0 taken 1553141 times.
✓ Branch 1 taken 6957900954 times.
6959454095 if (!is_in_world_bounds(x, y))
737 1553141 return rpos_t::None;
738
739 6957900954 int scr_dx = x / (16*16);
740 6957900954 int scr_dy = y / (11*16);
741 6957900954 int pos = COMBOPOS(x%256, y%176);
742 6957900954 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
743 6959454095 }
744 28725890 std::pair<int32_t, int32_t> COMBOXY_REGION(rpos_t rpos)
745 {
746 28725890 int scr_index = static_cast<int32_t>(rpos) / 176;
747 28725890 int scr_dx = scr_index % cur_region.screen_width;
748 28725890 int scr_dy = scr_index / cur_region.screen_width;
749 28725890 int pos = RPOS_TO_POS(rpos);
750 28725890 int x = scr_dx*16*16 + COMBOX(pos);
751 28725890 int y = scr_dy*11*16 + COMBOY(pos);
752 28725890 return {x, y};
753 }
754 182363 int32_t COMBOX_REGION(rpos_t rpos)
755 {
756 182363 auto [x, y] = COMBOXY_REGION(rpos);
757 182363 return x;
758 }
759 134192 int32_t COMBOY_REGION(rpos_t rpos)
760 {
761 134192 auto [x, y] = COMBOXY_REGION(rpos);
762 134192 return y;
763 }
764
765 70177 rpos_t COMBOPOS_REGION_INDEX(int32_t x, int32_t y)
766 {
767 DCHECK(is_in_world_bounds(x, y));
768
1/2
✓ Branch 0 taken 70177 times.
✗ Branch 1 not taken.
70177 if (!is_in_scrolling_region())
769 70177 return (rpos_t)(x + y * 16);
770
771 int scr_dx = x / 16;
772 int scr_dy = y / 11;
773 x %= 16;
774 y %= 11;
775 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + x + y * 16);
776 70177 }
777 70632 std::pair<int32_t, int32_t> COMBOXY_REGION_INDEX(rpos_t rpos)
778 {
779 70632 int scr_index = static_cast<int32_t>(rpos) / 176;
780 70632 int scr_dx = scr_index % cur_region.screen_width;
781 70632 int scr_dy = scr_index / cur_region.screen_width;
782 70632 int pos = RPOS_TO_POS(rpos);
783 70632 int x = scr_dx*16 + pos%16;
784 70632 int y = scr_dy*11 + pos/16;
785 70632 return {x, y};
786 }
787
788 92319438 int32_t mapind(int32_t map, int32_t screen)
789 {
790 92319438 return map * MAPSCRSNORMAL + screen;
791 }
792
793 FONT *get_zc_font(int index);
794
795 extern sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations;
796 extern movingblock mblock2; //mblock[4]?
797 extern portal mirror_portal;
798
799 void Z_message_d(const char *format,...)
800 {
801 #ifdef _DEBUG
802 char buf[512];
803 va_list ap;
804 va_start(ap, format);
805 vsprintf(buf, format, ap);
806 va_end(ap);
807
808 al_trace("%s",buf);
809 #else
810 format=format;
811 #endif
812 }
813
814
815
816 bool checktrigger=false;
817
818 void clear_dmap(word i)
819 {
820 DMaps[i].clear();
821 }
822
823 void clear_dmaps()
824 {
825 for(int32_t i=0; i<MAXDMAPS; i++)
826 {
827 clear_dmap(i);
828 }
829 }
830
831 235197567 int32_t isdungeon(int32_t dmap, int32_t screen)
832 {
833
2/2
✓ Branch 0 taken 235150207 times.
✓ Branch 1 taken 47360 times.
235197567 if (dmap < 0) dmap = cur_dmap;
834
835 // dungeons can have any dlevel above 0
836
2/2
✓ Branch 0 taken 133948122 times.
✓ Branch 1 taken 101249445 times.
235197567 if((DMaps[dmap].type&dmfTYPE) == dmDNGN)
837 {
838
2/2
✓ Branch 0 taken 9961 times.
✓ Branch 1 taken 101239484 times.
101249445 if (get_canonical_scr(cur_map, screen)->flags6&fCAVEROOM)
839 9961 return 0;
840
841 101239484 return 1;
842 }
843
844 // dlevels that aren't dungeons are caves
845
2/2
✓ Branch 0 taken 36827 times.
✓ Branch 1 taken 133911295 times.
133948122 if (get_canonical_scr(cur_map, screen)->flags6&fDUNGEONROOM)
846 36827 return 1;
847
848 133911295 return 0;
849 235197567 }
850
851 43127531 int32_t isdungeon(int32_t screen)
852 {
853 43127531 return isdungeon(cur_dmap, screen);
854 }
855
856 191937896 int32_t isdungeon()
857 {
858 191937896 return isdungeon(cur_dmap, Hero.current_screen);
859 }
860
861 92459 bool canPermSecret(int32_t dmap, int32_t screen)
862 {
863
2/2
✓ Branch 0 taken 13910 times.
✓ Branch 1 taken 78549 times.
92459 return (!isdungeon(dmap, screen) || get_qr(qr_DUNGEON_DMAPS_PERM_SECRETS));
864 }
865
866 1263951188 int32_t MAPCOMBO(int32_t x, int32_t y)
867 {
868 1263951188 x = vbound(x, 0, world_w-1);
869 1263951188 y = vbound(y, 0, world_h-1);
870 1263951188 int pos = COMBOPOS(x%256, y%176);
871 1263951188 mapscr* scr = get_scr_for_world_xy(x, y);
872 1263951188 return scr->data[pos];
873 }
874
875 //specific layers 1 to 6
876 1488655884 int32_t MAPCOMBOL(int32_t layer,int32_t x,int32_t y)
877 {
878 DCHECK(layer >= 1 && layer <= 6);
879
3/4
✓ Branch 0 taken 1468752430 times.
✓ Branch 1 taken 19903454 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1468752430 times.
1488655884 if (!is_in_world_bounds(x, y) || layer <= 0)
880 19903454 return 0;
881
882 1468752430 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
883
2/2
✓ Branch 0 taken 472740182 times.
✓ Branch 1 taken 996012248 times.
1468752430 if (!m->is_valid())
884 996012248 return 0;
885
886 472740182 int pos = COMBOPOS(x%256, y%176);
887 472740182 return m->data[pos];
888 1488655884 }
889
890 int32_t MAPCSETL(int32_t layer,int32_t x,int32_t y)
891 {
892 DCHECK(layer >= 1 && layer <= 6);
893 if (!is_in_world_bounds(x, y) || layer <= 0)
894 return 0;
895
896 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
897 if (!m->is_valid())
898 return 0;
899
900 int pos = COMBOPOS(x%256, y%176);
901 return m->cset[pos];
902 }
903
904 372352 int32_t MAPFLAGL(int32_t layer,int32_t x,int32_t y)
905 {
906 DCHECK(layer >= 1 && layer <= 6);
907
2/4
✓ Branch 0 taken 372352 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 372352 times.
372352 if (!is_in_world_bounds(x, y) || layer <= 0)
908 return 0;
909
910 372352 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
911
2/2
✓ Branch 0 taken 345286 times.
✓ Branch 1 taken 27066 times.
372352 if (!m->is_valid())
912 27066 return 0;
913
914 345286 int pos = COMBOPOS(x%256, y%176);
915 345286 return m->sflag[pos];
916 372352 }
917
918 40979 int32_t COMBOTYPEL(int32_t layer,int32_t x,int32_t y)
919 {
920 DCHECK(layer >= 1 && layer <= 6);
921
2/4
✓ Branch 0 taken 40979 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40979 times.
40979 if (!is_in_world_bounds(x, y) || layer <= 0)
922 return 0;
923
924 40979 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
925
2/2
✓ Branch 0 taken 40624 times.
✓ Branch 1 taken 355 times.
40979 if (!m->is_valid())
926 355 return 0;
927
928 40624 int pos = COMBOPOS(x%256, y%176);
929 40624 return combobuf[m->data[pos]].type;
930 40979 }
931
932 371064 int32_t MAPCOMBOFLAGL(int32_t layer,int32_t x,int32_t y)
933 {
934 DCHECK(layer >= 1 && layer <= 6);
935
2/4
✓ Branch 0 taken 371064 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 371064 times.
371064 if (!is_in_world_bounds(x, y) || layer <= 0)
936 return 0;
937
938 371064 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
939
2/2
✓ Branch 0 taken 343998 times.
✓ Branch 1 taken 27066 times.
371064 if (!m->is_valid())
940 27066 return 0;
941
942 343998 int pos = COMBOPOS(x%256, y%176);
943 343998 return combobuf[m->data[pos]].flag;
944 371064 }
945
946 // True if the FFC covers x, y and is not ethereal or a changer.
947 2536388256 bool ffcIsAt(const ffc_handle_t& ffc_handle, int32_t x, int32_t y)
948 {
949
2/2
✓ Branch 0 taken 750008244 times.
✓ Branch 1 taken 1786380012 times.
2536388256 if (ffc_handle.data() <= 0)
950 750008244 return false;
951
952
2/2
✓ Branch 0 taken 285071207 times.
✓ Branch 1 taken 1501308805 times.
1786380012 if((ffc_handle.ffc->flags&(ffc_changer|ffc_ethereal))!=0)
953 285071207 return false;
954
955 1501308805 int32_t fx = ffc_handle.ffc->x.getInt();
956 1501308805 int32_t w = ffc_handle.scr->ffEffectWidth(ffc_handle.i) - 1;
957
2/2
✓ Branch 0 taken 1390953542 times.
✓ Branch 1 taken 110355263 times.
1501308805 if (static_cast<uint32_t>(x - fx) > static_cast<uint32_t>(w))
958 1390953542 return false;
959
960 110355263 int32_t fy = ffc_handle.ffc->y.getInt();
961 110355263 int32_t h = ffc_handle.scr->ffEffectHeight(ffc_handle.i) - 1;
962
2/2
✓ Branch 0 taken 90405363 times.
✓ Branch 1 taken 19949900 times.
110355263 if (static_cast<uint32_t>(y - fy) > static_cast<uint32_t>(h))
963 90405363 return false;
964
965 19949900 return true;
966 2536388256 }
967
968 829861182 int32_t MAPFFCOMBO(int32_t x,int32_t y)
969 {
970
2/2
✓ Branch 0 taken 11864553 times.
✓ Branch 1 taken 817996629 times.
829861182 if (auto ffc_handle = getFFCAt(x, y))
971 11864553 return ffc_handle->data();
972 817996629 return 0;
973 829861182 }
974
975 207232 int32_t MAPCSET(int32_t x, int32_t y)
976 {
977
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207232 times.
207232 if (!is_in_world_bounds(x, y))
978 return 0;
979 207232 mapscr* scr = get_scr_for_world_xy(x, y);
980 207232 int pos = COMBOPOS(x%256, y%176);
981 207232 return scr->cset[pos];
982 207232 }
983
984 87058341 int32_t MAPFLAG(int32_t x, int32_t y)
985 {
986
2/2
✓ Branch 0 taken 28507 times.
✓ Branch 1 taken 87029834 times.
87058341 if (!is_in_world_bounds(x, y))
987 28507 return 0;
988 87029834 mapscr* scr = get_scr_for_world_xy(x, y);
989 87029834 int pos = COMBOPOS(x%256, y%176);
990 87029834 return scr->sflag[pos];
991 87058341 }
992
993 95535088 int32_t COMBOTYPE(int32_t x,int32_t y)
994 {
995 95535088 int32_t b=1;
996
2/2
✓ Branch 0 taken 64699764 times.
✓ Branch 1 taken 30835324 times.
95535088 if(x&8) b<<=2;
997
2/2
✓ Branch 0 taken 60202989 times.
✓ Branch 1 taken 35332099 times.
95535088 if(y&8) b<<=1;
998
999
2/2
✓ Branch 0 taken 191062429 times.
✓ Branch 1 taken 95519851 times.
286582280 for (int32_t i = 0; i <= 1; ++i)
1000 {
1001
2/2
✓ Branch 0 taken 158746666 times.
✓ Branch 1 taken 32315763 times.
191062429 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1002 {
1003
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 158746666 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
158746666 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x, y, i)) return cNONE;
1004 158746666 }
1005 else
1006 {
1007
4/4
✓ Branch 0 taken 18389 times.
✓ Branch 1 taken 32297374 times.
✓ Branch 2 taken 3152 times.
✓ Branch 3 taken 15237 times.
32315763 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x, y, i)) return cNONE;
1008 }
1009 191047192 }
1010
1011 95519851 newcombo const& cmb = combobuf[MAPCOMBO(x,y)];
1012
5/6
✓ Branch 0 taken 3536077 times.
✓ Branch 1 taken 91983774 times.
✓ Branch 2 taken 1909096 times.
✓ Branch 3 taken 1626981 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1909096 times.
95519851 if (cmb.type == cWATER && (cmb.walk&b) && ((cmb.walk>>4)&b))
1013 {
1014
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1909096 times.
1909096 if(cmb.usrflags&cflag4) return cSHALLOWWATER;
1015
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1909096 times.
1909096 if(cmb.usrflags&cflag3) return cNONE;
1016 1909096 }
1017 95519851 return cmb.type;
1018 95535088 }
1019
1020 59029538 int32_t FFCOMBOTYPE(int32_t x,int32_t y)
1021 {
1022 59029538 return combobuf[MAPFFCOMBO(x,y)].type;
1023 }
1024
1025 7152933 int32_t FFORCOMBO(int32_t x, int32_t y)
1026 {
1027
2/2
✓ Branch 0 taken 78428 times.
✓ Branch 1 taken 7074505 times.
7152933 if (auto ffc_handle = getFFCAt(x, y))
1028 78428 return ffc_handle->data();
1029
1030 7074505 return MAPCOMBO(x,y);
1031 7152933 }
1032
1033 int32_t FFORCOMBOTYPE(int32_t x, int32_t y)
1034 {
1035 for (int32_t i = 0; i <= 1; ++i)
1036 {
1037 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1038 {
1039 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1040 }
1041 else
1042 {
1043 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1044 }
1045 }
1046 int32_t b=1;
1047
1048 if(x&8) b<<=2;
1049
1050 if(y&8) b<<=1;
1051 newcombo const& cmb = combobuf[FFORCOMBO(x,y)];
1052 if (cmb.type == cWATER && (cmb.usrflags&cflag4) && (cmb.walk&b)) return cSHALLOWWATER;
1053 if (cmb.type == cWATER && (cmb.usrflags&cflag3) && (cmb.walk&b)) return cNONE;
1054 return cmb.type;
1055 }
1056
1057 int32_t FFORCOMBO_L(int32_t layer, int32_t x, int32_t y)
1058 {
1059 if (auto ffc_handle = getFFCAt(x, y))
1060 return ffc_handle->data();
1061
1062 return layer ? MAPCOMBOL(layer, x, y) : MAPCOMBO(x,y);
1063 }
1064
1065 int32_t FFORCOMBOTYPE_L(int32_t layer, int32_t x, int32_t y)
1066 {
1067 return combobuf[FFORCOMBO_L(layer,x,y)].type;
1068 }
1069
1070 83411135 int32_t MAPCOMBOFLAG(int32_t x,int32_t y)
1071 {
1072
2/2
✓ Branch 0 taken 28219 times.
✓ Branch 1 taken 83382916 times.
83411135 if (!is_in_world_bounds(x, y))
1073 28219 return 0;
1074
1075 83382916 mapscr* scr = get_scr_for_world_xy(x, y);
1076 83382916 int pos = COMBOPOS(x%256, y%176);
1077 83382916 return combobuf[scr->data[pos]].flag;
1078 83411135 }
1079
1080 68112012 int32_t MAPFFCOMBOFLAG(int32_t x,int32_t y)
1081 {
1082
2/2
✓ Branch 0 taken 777663 times.
✓ Branch 1 taken 67334349 times.
68112012 if (auto ffc_handle = getFFCAt(x, y))
1083 777663 return ffc_handle->cflag();
1084
1085 67334349 return 0;
1086 68112012 }
1087
1088 1237799194 std::optional<ffc_handle_t> getFFCAt(int32_t x, int32_t y)
1089 {
1090 2784764985 return find_ffc([&](const ffc_handle_t& ffc_handle) {
1091 1546965791 return ffcIsAt(ffc_handle, x, y);
1092 });
1093 }
1094
1095 3051 int32_t MAPCOMBO(const rpos_handle_t& rpos_handle)
1096 {
1097
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3051 times.
3051 if (!rpos_handle.scr->is_valid()) return 0;
1098 3051 return rpos_handle.data();
1099 3051 }
1100
1101 3018236659 int32_t MAPCOMBO2(int32_t layer, int32_t x, int32_t y)
1102 {
1103 DCHECK_LAYER_NEG1_INDEX(layer);
1104
2/2
✓ Branch 0 taken 22065451 times.
✓ Branch 1 taken 2996171208 times.
3018236659 if (!is_in_world_bounds(x, y)) return 0;
1105
2/2
✓ Branch 0 taken 2896990235 times.
✓ Branch 1 taken 99180973 times.
2996171208 if (layer == -1) return MAPCOMBO(x, y);
1106
1107 2896990235 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1108
2/2
✓ Branch 0 taken 1796564049 times.
✓ Branch 1 taken 1100426186 times.
2896990235 if (!rpos_handle.scr->is_valid()) return 0;
1109
1110 1100426186 return rpos_handle.data();
1111 3018236659 }
1112
1113 19160886 static void _handle_screen_load_trigger(const combined_handle_t& handle)
1114 {
1115 19160886 auto cid = handle.data();
1116 19160886 auto* cmb = &handle.combo();
1117 19160886 bool done = false;
1118 19160886 std::set<int32_t> visited;
1119
2/2
✓ Branch 0 taken 19160886 times.
✓ Branch 1 taken 19160886 times.
38321772 while(!done)
1120 {
1121
2/4
✓ Branch 0 taken 19160886 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19160886 times.
19160886 if(visited.contains(cid))
1122 {
1123 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
1124 break; // prevent infinite loop
1125 }
1126
1/2
✓ Branch 0 taken 19160886 times.
✗ Branch 1 not taken.
19160886 visited.insert(cid);
1127
1128 19160886 done = true; // don't loop again unless something changes
1129
1/2
✓ Branch 0 taken 19160886 times.
✗ Branch 1 not taken.
20045029 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
1130 884143 return trig.trigger_flags.get(TRIGFLAG_SCREENLOAD);
1131 });
1132
2/4
✓ Branch 0 taken 19160886 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19160886 times.
19160886 if(handle.data() != cid)
1133 {
1134 cid = handle.data();
1135 cmb = &handle.combo();
1136 done = false; // loop again for the new combo
1137 }
1138 }
1139 19160886 }
1140 52906 static void handle_screen_load_trigger(const screen_handles_t& screen_handles)
1141 {
1142 52906 for_every_combo_in_screen(screen_handles, _handle_screen_load_trigger);
1143 52906 }
1144 36496 void handle_region_load_trigger()
1145 {
1146
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 36344 times.
36496 if (is_in_scrolling_region())
1147 {
1148
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 19456 times.
19608 for (int screen = 0; screen < 128; screen++)
1149 {
1150
2/2
✓ Branch 0 taken 18156 times.
✓ Branch 1 taken 1300 times.
19456 if (is_in_current_region(screen))
1151 1300 handle_screen_load_trigger(create_screen_handles_one(get_scr(screen)));
1152 19456 }
1153 152 }
1154 36344 else handle_screen_load_trigger(create_screen_handles_one(get_scr(Hero.current_screen)));
1155 36496 }
1156
1157 15262 static void apply_state_changes_to_screen(mapscr& scr, int32_t map, int32_t screen, int32_t flags, bool secrets_do_replay_comment)
1158 {
1159 15262 auto screen_handles = create_screen_handles_one(&scr);
1160
1161
3/4
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 14723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 539 times.
15262 if ((flags & mSECRET) && canPermSecret(cur_dmap, screen))
1162 {
1163 539 reveal_hidden_stairs(&scr, screen, false);
1164 539 bool do_layers = false;
1165 539 bool from_active_screen = false;
1166 539 trigger_secrets_for_screen_internal(screen_handles, do_layers, from_active_screen, -3, secrets_do_replay_comment);
1167 539 }
1168
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if (flags & mLIGHTBEAM)
1169 {
1170 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
1171 if (rpos_handle.ctype() == cLIGHTTARGET)
1172 {
1173 if (!(rpos_handle.combo().usrflags&cflag1)) //Unlit version
1174 rpos_handle.increment_data();
1175 }
1176 });
1177 }
1178
1179 15262 int lvl = DMaps[cur_dmap].level;
1180 15262 toggle_switches(game->lvlswitches[lvl], true, screen_handles);
1181 15262 toggle_gswitches_load(screen_handles);
1182
1183
2/2
✓ Branch 0 taken 15170 times.
✓ Branch 1 taken 92 times.
15262 if(flags&mLOCKBLOCK) // if special stuff done before
1184 {
1185 92 remove_screenstatecombos2(screen_handles, false, cLOCKBLOCK, cLOCKBLOCK2);
1186 92 }
1187
1188
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSLOCKBLOCK) // if special stuff done before
1189 {
1190 remove_screenstatecombos2(screen_handles, false, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
1191 }
1192
1193
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1194 {
1195 remove_screenstatecombos2(screen_handles, false, cCHEST, cCHEST2);
1196 }
1197
1198
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1199 {
1200 remove_screenstatecombos2(screen_handles, false, cLOCKEDCHEST, cLOCKEDCHEST2);
1201 }
1202
1203
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSCHEST) // if special stuff done before
1204 {
1205 remove_screenstatecombos2(screen_handles, false, cBOSSCHEST, cBOSSCHEST2);
1206 }
1207
1208
1209 15262 int mi = mapind(map, screen);
1210 15262 clear_xdoors_mi(screen_handles, mi);
1211 15262 clear_xstatecombos_mi(screen_handles, mi);
1212
1213 15262 handle_screen_load_trigger(screen_handles);
1214 15262 }
1215
1216 40981 std::optional<mapscr> load_temp_mapscr_and_apply_secrets(int32_t map, int32_t screen, int32_t layer, bool secrets, bool secrets_do_replay_comment)
1217 {
1218
2/4
✓ Branch 0 taken 40981 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40981 times.
40981 if (map < 0 || screen < 0)
1219 return std::nullopt;
1220
1221 40981 const mapscr* source = get_canonical_scr(map, screen);
1222
2/2
✓ Branch 0 taken 39256 times.
✓ Branch 1 taken 1725 times.
40981 if (!source->is_valid())
1223 1725 return std::nullopt;
1224
1225
2/2
✓ Branch 0 taken 7936 times.
✓ Branch 1 taken 31320 times.
39256 if (layer >= 0)
1226 {
1227
2/2
✓ Branch 0 taken 23994 times.
✓ Branch 1 taken 7326 times.
31320 if (source->layermap[layer] <= 0)
1228 23994 return std::nullopt;
1229
1230 7326 source = get_canonical_scr(source->layermap[layer] - 1, source->layerscreen[layer]);
1231
1/2
✓ Branch 0 taken 7326 times.
✗ Branch 1 not taken.
7326 if (!source->is_valid())
1232 return std::nullopt;
1233 7326 }
1234
1235
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 int flags = secrets ? game->maps[mapind(map, screen)] : 0;
1236 15262 mapscr scr = *source;
1237
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 apply_state_changes_to_screen(scr, map, screen, flags, secrets_do_replay_comment);
1238
1239
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 return scr;
1240 40981 }
1241
1242 14990 static int32_t MAPCOMBO3_impl(int32_t map, int32_t screen, int32_t layer, int32_t pos, bool secrets)
1243 {
1244
2/4
✓ Branch 0 taken 14990 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14990 times.
14990 if (map < 0 || screen < 0) return 0;
1245
1246
2/4
✓ Branch 0 taken 14990 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14990 times.
14990 if(pos>175 || pos < 0)
1247 return 0;
1248
1249 // TODO: consider caching this (invalidate on any modification via scripting, or anything
1250 // `apply_state_changes_to_screen` checks).
1251
4/5
✓ Branch 0 taken 4736 times.
✓ Branch 1 taken 10254 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4736 times.
✓ Branch 4 taken 10254 times.
19726 if (auto s = load_temp_mapscr_and_apply_secrets(map, screen, layer, secrets))
1252 4736 return s->data[pos];
1253
1254 10254 return 0;
1255 14990 }
1256
1257 // Read from the current temporary screens or, if (map, screen) is not loaded,
1258 // load that screen and apply the relevant secrets before evaluating the combo at that position.
1259 251421596 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets)
1260 {
1261 DCHECK_LAYER_NEG1_INDEX(layer);
1262 DCHECK(map >= 0 && screen >= 0);
1263
1264
2/2
✓ Branch 0 taken 251406606 times.
✓ Branch 1 taken 14990 times.
251421596 if (is_in_current_region(map, screen)) return MAPCOMBO2(layer, x, y);
1265
1266 // Screen is not in the current region, so we have to load and trigger some secrets.
1267 14990 int pos = COMBOPOS(x, y);
1268 14990 return MAPCOMBO3_impl(map, screen, layer, pos, secrets);
1269 251421596 }
1270
1271 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, rpos_t rpos, bool secrets)
1272 {
1273 DCHECK_LAYER_NEG1_INDEX(layer);
1274 DCHECK(map >= 0 && screen >= 0);
1275 DCHECK(is_valid_rpos(rpos));
1276
1277 if (is_in_current_region(map, screen)) return MAPCOMBO(get_rpos_handle(rpos, layer + 1));
1278
1279 // Screen is not currently loaded, so we have to load and trigger some secrets.
1280 return MAPCOMBO3_impl(map, screen, layer, RPOS_TO_POS(rpos), secrets);
1281 }
1282
1283 int32_t MAPCSET2(int32_t layer,int32_t x,int32_t y)
1284 {
1285 DCHECK_LAYER_NEG1_INDEX(layer);
1286 if (!is_in_world_bounds(x, y))
1287 return 0;
1288 if (layer == -1) return MAPCSET(x, y);
1289
1290 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1291 if (!rpos_handle.scr->is_valid()) return 0;
1292
1293 return rpos_handle.cset();
1294 }
1295
1296 102412209 int32_t MAPFLAG2(int32_t layer,int32_t x,int32_t y)
1297 {
1298 DCHECK_LAYER_NEG1_INDEX(layer);
1299
3/4
✓ Branch 0 taken 5385623 times.
✓ Branch 1 taken 97026586 times.
✓ Branch 2 taken 5385623 times.
✗ Branch 3 not taken.
102412209 if (!get_qr(qr_BUGGED_LAYERED_FLAGS) && (!is_in_world_bounds(x, y)))
1300 return 0;
1301
2/2
✓ Branch 0 taken 84274547 times.
✓ Branch 1 taken 18137662 times.
102412209 if (layer == -1) return MAPFLAG(x, y);
1302
1303 84274547 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1304
2/2
✓ Branch 0 taken 63730019 times.
✓ Branch 1 taken 20544528 times.
84274547 if (!rpos_handle.scr->is_valid()) return 0;
1305
1306 20544528 return rpos_handle.sflag();
1307 102412209 }
1308
1309 int32_t COMBOTYPE2(int32_t layer,int32_t x,int32_t y)
1310 {
1311 if(layer < 1)
1312 {
1313 for (int32_t i = layer+1; i <= 1; ++i)
1314 {
1315 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1316 {
1317 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1318 }
1319 else
1320 {
1321 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1322 }
1323 }
1324 }
1325 if(layer==-1) return COMBOTYPE(x,y);
1326
1327 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1328 if (!rpos_handle.scr->is_valid()) return 0;
1329
1330 return rpos_handle.ctype();
1331 }
1332
1333 // Returns the flag for the combo at the given position.
1334 // This is also known as an "inherent flag".
1335 100578885 int32_t MAPCOMBOFLAG2(int32_t layer,int32_t x,int32_t y)
1336 {
1337 DCHECK_LAYER_NEG1_INDEX(layer);
1338
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 100578597 times.
100578885 if (!is_in_world_bounds(x, y))
1339 288 return 0;
1340
2/2
✓ Branch 0 taken 84177975 times.
✓ Branch 1 taken 16400622 times.
100578597 if (layer == -1) return MAPCOMBOFLAG(x, y);
1341
1342 84177975 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1343
2/2
✓ Branch 0 taken 63748345 times.
✓ Branch 1 taken 20429630 times.
84177975 if (!rpos_handle.scr->is_valid()) return 0;
1344
1345 20429630 return rpos_handle.cflag();
1346 100578885 }
1347
1348 11726263 bool HASFLAG(int32_t flag, int32_t layer, rpos_t rpos)
1349 {
1350 DCHECK_LAYER_ZERO_INDEX(layer);
1351 11726263 auto rpos_handle = get_rpos_handle(rpos, layer);
1352
2/2
✓ Branch 0 taken 4499782 times.
✓ Branch 1 taken 7226481 times.
11726263 if (!rpos_handle.scr->is_valid()) return false;
1353
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 7221916 times.
7226481 if (rpos_handle.sflag() == flag) return true;
1354
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 7184211 times.
7221916 if (rpos_handle.cflag() == flag) return true;
1355 7184211 return false;
1356 11726263 }
1357
1358 1711265 bool HASFLAG_ANY(int32_t flag, rpos_t rpos)
1359 {
1360 DCHECK(is_valid_rpos(rpos));
1361
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1711265 times.
1711265 if (rpos > region_max_rpos) return false;
1362
1363
2/2
✓ Branch 0 taken 11726263 times.
✓ Branch 1 taken 1668995 times.
13395258 for(auto q = 0; q < 7; ++q)
1364 {
1365
2/2
✓ Branch 0 taken 42270 times.
✓ Branch 1 taken 11683993 times.
11726263 if(HASFLAG(flag, q, rpos))
1366 42270 return true;
1367 11683993 }
1368 1668995 return false;
1369 1711265 }
1370
1371 const char *screenstate_string[32] =
1372 {
1373 "Door Up", "Door Down", "Door Left", "Door Right", "Item", "Special Item", "Some Enemies Never Return",
1374 "Temporary No Return", "Lock Blocks", "Boss Lock Blocks", "Chests", "Locked Chests",
1375 "Boss Locked Chests", "Secrets", "Visited", "Light Beams",
1376 "All Enemies Don't Return", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1377 "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1378 };
1379
1380 36562 void eventlog_mapflags()
1381 {
1382 36562 std::ostringstream oss;
1383
1384 36562 int mi = mapind(cur_map, home_screen);
1385
1/2
✓ Branch 0 taken 36562 times.
✗ Branch 1 not taken.
36562 dword g = game->maps[mi];
1386
1387
2/4
✓ Branch 0 taken 36562 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36562 times.
✗ Branch 3 not taken.
36562 oss << fmt::format("Screen ({}, {:02X})", cur_map+1, home_screen);
1388
2/2
✓ Branch 0 taken 15710 times.
✓ Branch 1 taken 20852 times.
36562 if(g) // Main States
1389 {
1390 static const int order[] =
1391 {
1392 mSECRET, mITEM, mSPECIALITEM, mLOCKBLOCK, mBOSSLOCKBLOCK,
1393 mCHEST, mLOCKEDCHEST, mBOSSCHEST,
1394 mDOOR_UP, mDOOR_DOWN, mDOOR_LEFT, mDOOR_RIGHT,
1395 mNEVERRET, mTMPNORET, mLIGHTBEAM, mNO_ENEMIES_RETURN
1396 };
1397
1398
1/2
✓ Branch 0 taken 15710 times.
✗ Branch 1 not taken.
15710 oss << " [";
1399 15710 bool comma = false;
1400
2/2
✓ Branch 0 taken 15710 times.
✓ Branch 1 taken 251360 times.
267070 for(int fl : order)
1401 {
1402
2/2
✓ Branch 0 taken 9640 times.
✓ Branch 1 taken 241720 times.
251360 if(!(g&fl))
1403 241720 continue;
1404 9640 byte ind = byte(log2(double(fl)));
1405
2/2
✓ Branch 0 taken 2072 times.
✓ Branch 1 taken 7568 times.
9640 if(comma)
1406
1/2
✓ Branch 0 taken 2072 times.
✗ Branch 1 not taken.
2072 oss << ", ";
1407
1/2
✓ Branch 0 taken 9640 times.
✗ Branch 1 not taken.
9640 oss << screenstate_string[ind];
1408 9640 comma = true;
1409 }
1410
1/2
✓ Branch 0 taken 15710 times.
✗ Branch 1 not taken.
15710 oss << "]";
1411 15710 }
1412
3/4
✓ Branch 0 taken 36562 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 36506 times.
36562 if(game->xstates[mi]) // ExStates
1413 {
1414
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 oss << " Ex[";
1415 56 bool comma = false;
1416
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 1792 times.
1848 for(byte fl = 0; fl < 32; ++fl)
1417 {
1418
3/4
✓ Branch 0 taken 1792 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 1715 times.
1792 if(game->xstates[mi] & (1<<fl))
1419 {
1420
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 56 times.
77 if(comma)
1421
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 oss << ", ";
1422
1/2
✓ Branch 0 taken 77 times.
✗ Branch 1 not taken.
77 oss << int(fl);
1423 77 comma = true;
1424 77 }
1425 1792 }
1426
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 oss << "]";
1427 56 }
1428 { // ExDoors
1429
2/2
✓ Branch 0 taken 36562 times.
✓ Branch 1 taken 146248 times.
182810 for(int q = 0; q < 4; ++q)
1430 {
1431 146248 bool comma = false;
1432
3/4
✓ Branch 0 taken 146248 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 146246 times.
✓ Branch 3 taken 2 times.
146248 if(auto v = game->xdoors[mi][q])
1433 {
1434
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(comma)
1435 oss << ",";
1436
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else oss << " ExDoor";
1437
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 oss << "[" << dirstr[q];
1438
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 for(int fl = 0; fl < 8; ++fl)
1439
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
19 if(v & (1<<fl))
1440
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 oss << " " << int(fl);
1441
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 oss << "]";
1442 2 comma = true;
1443 2 }
1444 146248 }
1445 }
1446
2/4
✓ Branch 0 taken 36562 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 36562 times.
36562 Z_eventlog("%s\n", oss.str().c_str());
1447 36562 }
1448
1449 // set specific flag
1450 5932 void setmapflag(mapscr* scr, uint32_t flag)
1451 {
1452
2/2
✓ Branch 0 taken 5919 times.
✓ Branch 1 taken 13 times.
5932 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1453 5932 int mi = mapind(cur_map, scr->screen);
1454 5932 setmapflag_mi(scr, mi, flag);
1455 5932 }
1456 57 void setmapflag_homescr(uint32_t flag)
1457 {
1458 57 int mi = mapind(cur_map, home_screen);
1459 57 setmapflag_mi(origin_scr, mi, flag);
1460 57 }
1461 2065 void setmapflag_mi(int32_t mi, uint32_t flag)
1462 {
1463 2065 byte cscr = mi&((1<<7)-1);
1464 2065 byte cmap = (mi>>7);
1465 2065 mapscr* scr = origin_scr;
1466
2/2
✓ Branch 0 taken 835 times.
✓ Branch 1 taken 1230 times.
2065 if (is_in_current_region(cmap, cscr))
1467 1230 scr = get_scr(cmap, cscr);
1468
1469 2065 setmapflag_mi(scr, mi, flag);
1470 2065 }
1471
1472 8877 static void log_state_change(int map, int screen, std::string action)
1473 {
1474
6/6
✓ Branch 0 taken 1937 times.
✓ Branch 1 taken 6940 times.
✓ Branch 2 taken 996 times.
✓ Branch 3 taken 941 times.
✓ Branch 4 taken 352 times.
✓ Branch 5 taken 644 times.
8877 if (is_in_current_region(map, screen) || (map == cur_map && screen == home_screen))
1475 7292 Z_eventlog("[Map %d, Screen %02X (current)] %s\n", map + 1, screen, action.c_str());
1476 else
1477 1585 Z_eventlog("[Map %d, Screen %02X] %s\n", map + 1, screen, action.c_str());
1478 8877 }
1479
1480 8054 void setmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag)
1481 {
1482 8054 byte cscr = mi&((1<<7)-1);
1483 8054 byte cmap = (mi>>7);
1484
1485 8054 double temp=log2((double)flag);
1486
1/2
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
8054 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1487 8054 const char* replay_state_string = state_string;
1488
2/2
✓ Branch 0 taken 7534 times.
✓ Branch 1 taken 520 times.
8054 if(temp == 6) replay_state_string = "No Return";
1489
1490
3/4
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1596 times.
✓ Branch 3 taken 6458 times.
8054 if (replay_is_active() && !(game->maps[mi] & flag))
1491
1/2
✓ Branch 0 taken 6458 times.
✗ Branch 1 not taken.
6458 replay_step_comment(fmt::format("map {} scr {} flag {}", cmap, cscr, replay_state_string));
1492 8054 game->maps[mi] |= flag;
1493
1/2
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
8054 log_state_change(cmap, cscr, fmt::format("State set: {}", state_string));
1494
1495
2/2
✓ Branch 0 taken 2518 times.
✓ Branch 1 taken 5536 times.
8054 if((scr->nocarry&flag)!=flag)
1496 {
1497 5536 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1498 5536 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1499
1500 5536 std::vector<int32_t> done;
1501
2/2
✓ Branch 0 taken 5423 times.
✓ Branch 1 taken 113 times.
5536 bool looped = (nmap==cmap+1 && nscr==cscr);
1502
1503
6/6
✓ Branch 0 taken 458 times.
✓ Branch 1 taken 5485 times.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 407 times.
✓ Branch 4 taken 407 times.
✓ Branch 5 taken 5536 times.
5943 while((nmap!=0) && !looped && !(nscr>=128))
1504 {
1505
3/4
✓ Branch 0 taken 407 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 191 times.
✓ Branch 3 taken 216 times.
407 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1506 {
1507
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 log_state_change(nmap, nscr, "State change carried over");
1508
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 if (replay_is_active())
1509
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 replay_step_comment(fmt::format("map {} scr {} flag {} carry", nmap, nscr, replay_state_string));
1510
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 game->maps[((nmap-1)<<7)+nscr] |= flag;
1511 216 }
1512
1513 407 cmap=nmap;
1514 407 cscr=nscr;
1515 407 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1516 407 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1517
1518
2/2
✓ Branch 0 taken 916 times.
✓ Branch 1 taken 407 times.
1323 for(auto it = done.begin(); it != done.end(); it++)
1519 {
1520
2/2
✓ Branch 0 taken 865 times.
✓ Branch 1 taken 51 times.
916 if(*it == ((nmap-1)<<7)+nscr)
1521 51 looped = true;
1522 916 }
1523
1524
1/2
✓ Branch 0 taken 407 times.
✗ Branch 1 not taken.
407 done.push_back(((nmap-1)<<7)+nscr);
1525 }
1526 5536 }
1527 8054 }
1528
1529 void unsetmapflag_home(uint32_t flag, bool anyflag)
1530 {
1531 int mi = mapind(cur_map, home_screen);
1532 unsetmapflag_mi(origin_scr, mi, flag, anyflag);
1533 }
1534
1535 void unsetmapflag(mapscr* scr, uint32_t flag, bool anyflag)
1536 {
1537 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1538 int mi = mapind(cur_map, scr->screen);
1539 unsetmapflag_mi(scr, mi, flag, anyflag);
1540 }
1541
1542 471 void unsetmapflag_mi(int32_t mi, uint32_t flag, bool anyflag)
1543 {
1544 471 byte cscr = mi&((1<<7)-1);
1545 471 byte cmap = (mi>>7);
1546 471 mapscr* scr = origin_scr;
1547
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if (is_in_current_region(cmap, cscr))
1548 11 scr = get_scr(cmap, cscr);
1549
1550 471 unsetmapflag_mi(scr, mi, flag, anyflag);
1551 471 }
1552
1553 471 void unsetmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag, bool anyflag)
1554 {
1555 471 byte cscr = mi&((1<<7)-1);
1556 471 byte cmap = (mi>>7);
1557
1558
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if(anyflag)
1559 460 game->maps[mi] &= ~flag;
1560
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 else if(flag==mITEM || flag==mSPECIALITEM)
1561 {
1562 if(!(scr->flags4&fNOITEMRESET))
1563 game->maps[mi] &= ~flag;
1564 }
1565 11 else game->maps[mi] &= ~flag;
1566
1567 471 double temp=log2((double)flag);
1568
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1569
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 log_state_change(cmap, cscr, fmt::format("State unset: {}", state_string));
1570
1571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 471 times.
471 if((scr->nocarry&flag)!=flag)
1572 {
1573 471 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1574 471 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1575
1576 471 std::vector<int32_t> done;
1577
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 5 times.
471 bool looped = (nmap==cmap+1 && nscr==cscr);
1578
1579
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 471 times.
555 while((nmap!=0) && !looped && !(nscr>=128))
1580 {
1581
3/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 72 times.
84 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1582 {
1583
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 log_state_change(nmap, nscr, "State change carried over");
1584
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 game->maps[((nmap-1)<<7)+nscr] &= ~flag;
1585 72 }
1586
1587 84 cmap=nmap;
1588 84 cscr=nscr;
1589 84 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1590 84 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1591
1592
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 546 times.
630 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1593 {
1594
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 6 times.
546 if(*it == ((nmap-1)<<7)+nscr)
1595 6 looped = true;
1596 546 }
1597
1598
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 done.push_back(((nmap-1)<<7)+nscr);
1599 }
1600 471 }
1601 471 }
1602
1603 51936217 bool getmapflag(int32_t screen, uint32_t flag)
1604 {
1605
2/2
✓ Branch 0 taken 1345925 times.
✓ Branch 1 taken 50590292 times.
51936217 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1606 51936217 return (game->maps[mi] & flag) != 0;
1607 }
1608 6410813 bool getmapflag(mapscr* scr, uint32_t flag)
1609 {
1610 6410813 return getmapflag(scr->screen, flag);
1611 }
1612
1613 57 void setxmapflag(int32_t screen, uint32_t flag)
1614 {
1615
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1616 57 setxmapflag_mi(mi, flag);
1617 57 }
1618 59 void setxmapflag_mi(int32_t mi, uint32_t flag)
1619 {
1620
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if(game->xstates[mi] & flag) return;
1621 59 byte cscr = mi&((1<<7)-1);
1622 59 byte cmap = (mi>>7);
1623
1624 59 byte temp=(byte)log2((double)flag);
1625
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
59 log_state_change(cmap, cscr, fmt::format("ExtraState set: {}", temp));
1626
1627 59 game->xstates[mi] |= flag;
1628
1629 59 mapscr* scr = origin_scr;
1630
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if (is_in_current_region(cmap, cscr))
1631 59 scr = get_scr(cmap, cscr);
1632
1633
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
59 if((scr->exstate_carry&flag)==flag)
1634 {
1635 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1636 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1637
1638 std::vector<int32_t> done;
1639 bool looped = (nmap==cmap+1 && nscr==cscr);
1640
1641 while((nmap!=0) && !looped && !(nscr>=128))
1642 {
1643 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1644 {
1645 log_state_change(nmap, nscr, "ExState change carried over");
1646 if (replay_is_active())
1647 replay_step_comment(fmt::format("map {} scr {} exstate {} carry", nmap, nscr, temp));
1648 game->xstates[((nmap-1)<<7)+nscr] |= flag;
1649 }
1650
1651 cmap=nmap;
1652 cscr=nscr;
1653 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1654 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1655
1656 for(auto it = done.begin(); it != done.end(); it++)
1657 {
1658 if(*it == ((nmap-1)<<7)+nscr)
1659 looped = true;
1660 }
1661
1662 done.push_back(((nmap-1)<<7)+nscr);
1663 }
1664 }
1665 59 }
1666 2 void unsetxmapflag(int32_t screen, uint32_t flag)
1667 {
1668
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1669 2 unsetxmapflag_mi(mi, flag);
1670 2 }
1671 2 void unsetxmapflag_mi(int32_t mi, uint32_t flag)
1672 {
1673
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(!(game->xstates[mi] & flag)) return;
1674 1 byte cscr = mi&((1<<7)-1);
1675 1 byte cmap = (mi>>7);
1676 1 byte temp=(byte)log2((double)flag);
1677
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 log_state_change(cmap, cscr, fmt::format("ExtraState unset: {}", temp));
1678 1 game->xstates[mi] &= ~flag;
1679
1680 1 mapscr* scr = origin_scr;
1681
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (is_in_current_region(cmap, cscr))
1682 1 scr = get_scr(cmap, cscr);
1683
1684
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if((scr->exstate_carry&flag)==flag)
1685 {
1686 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1687 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1688
1689 std::vector<int32_t> done;
1690 bool looped = (nmap==cmap+1 && nscr==cscr);
1691
1692 while((nmap!=0) && !looped && !(nscr>=128))
1693 {
1694 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1695 {
1696 log_state_change(nmap, nscr, "ExState change carried over");
1697 game->xstates[((nmap-1)<<7)+nscr] &= ~flag;
1698 }
1699
1700 cmap=nmap;
1701 cscr=nscr;
1702 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1703 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1704
1705 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1706 {
1707 if(*it == ((nmap-1)<<7)+nscr)
1708 looped = true;
1709 }
1710
1711 done.push_back(((nmap-1)<<7)+nscr);
1712 }
1713 }
1714 2 }
1715 82 bool getxmapflag(int32_t screen, uint32_t flag)
1716 {
1717
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 82 times.
82 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1718 82 return getxmapflag_mi(mi, flag);
1719 }
1720 488421536 bool getxmapflag_mi(int32_t mi, uint32_t flag)
1721 {
1722 488421536 return (game->xstates[mi] & flag) != 0;
1723 }
1724
1725 4 void setxdoor_mi(uint mi, uint dir, uint ind, bool state)
1726 {
1727
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if(mi > game->xdoors.size() || dir > 3 || ind > 8)
1728 return;
1729
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!(game->xdoors[mi][dir] & (1<<ind)) == !state)
1730 return;
1731
1732
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 SETFLAG(game->xdoors[mi][dir], 1<<ind, state);
1733
1734 4 int cscr = mi % MAPSCRSNORMAL;
1735 4 int cmap = mi / MAPSCRSNORMAL;
1736
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (state)
1737
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] set", dirstr[dir], ind));
1738 else
1739 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] unset", dirstr[dir], ind));
1740 4 }
1741 488421449 bool getxdoor_mi(uint mi, uint dir, uint ind)
1742 {
1743
3/6
✓ Branch 0 taken 488421449 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 488421449 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 488421449 times.
488421449 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1744 return false;
1745 488421449 return (game->xdoors[mi][dir] & (1<<ind));
1746 488421449 }
1747 9 bool getxdoor(int32_t screen, uint dir, uint ind)
1748 {
1749 9 int mi = mapind(cur_map, screen);
1750 9 return getxdoor_mi(mi,dir,ind);
1751 }
1752
1753 401 void set_doorstate_mi(uint mi, uint dir)
1754 {
1755
1/2
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
401 if(dir >= 4)
1756 return;
1757 401 setmapflag_mi(mi, mDOOR_UP << dir);
1758
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if(auto di = nextscr_mi(mi, dir))
1759 400 setmapflag_mi(*di, mDOOR_UP << oppositeDir[dir]);
1760 401 }
1761 401 void set_doorstate(uint screen, uint dir)
1762 {
1763 401 int mi = mapind(cur_map, screen);
1764 401 set_doorstate_mi(mi, dir);
1765 401 }
1766
1767 2 void set_xdoorstate_mi(uint mi, uint dir, uint ind, bool state)
1768 {
1769
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1770 return;
1771 2 setxdoor_mi(mi, dir, ind, state);
1772
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(auto di = nextscr_mi(mi, dir))
1773 2 setxdoor_mi(*di, oppositeDir[dir], ind, state);
1774 2 }
1775
1776 2 void set_xdoorstate(int32_t screen,uint dir, uint ind, bool state)
1777 {
1778 2 int mi = mapind(cur_map, screen);
1779 2 set_xdoorstate_mi(mi, dir, ind, state);
1780 2 }
1781
1782 57 int32_t WARPCODE(int32_t dmap,int32_t screen,int32_t dw)
1783 // returns: -1 = not a warp screen
1784 // 0+ = warp screen code ( high byte=dmap, low byte=scr )
1785 {
1786 57 const mapscr *scr = get_canonical_scr(DMaps[dmap].map, screen);
1787
1788
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(scr->room!=rWARP)
1789 return -1;
1790
1791 57 int32_t ring=scr->catchall;
1792 57 int32_t size=QMisc.warp[ring].size;
1793
1794
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if(size==0)
1795 return -2;
1796
1797 57 int32_t index=-1;
1798
1799
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 57 times.
346 for(int32_t i=0; i<size; i++)
1800
6/6
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 173 times.
✓ Branch 5 taken 57 times.
289 if(dmap==QMisc.warp[ring].dmap[i] && screen==
1801 346 (QMisc.warp[ring].scr[i] + DMaps[dmap].xoff))
1802 57 index=i;
1803
1804
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(index==-1)
1805 return -3;
1806
1807 57 index = (index+dw)%size;
1808 57 return (QMisc.warp[ring].dmap[index] << 8) + QMisc.warp[ring].scr[index];
1809 57 }
1810
1811 15359538 void update_combo_cycling()
1812 {
1813 15359538 auto& combo_cache = combo_caches::can_cycle;
1814
1815 static int32_t newdata[176];
1816 static int32_t newcset[176];
1817 static bool initialized=false;
1818
1819 // Just a simple bit of optimization
1820
2/2
✓ Branch 0 taken 15359217 times.
✓ Branch 1 taken 321 times.
15359538 if(!initialized)
1821 {
1822
2/2
✓ Branch 0 taken 56496 times.
✓ Branch 1 taken 321 times.
56817 for(int32_t i=0; i<176; i++)
1823 {
1824 56496 newdata[i]=-1;
1825 56496 newcset[i]=-1;
1826 56496 }
1827
1828 321 initialized=true;
1829 321 }
1830
1831 15359538 std::set<uint16_t> restartanim;
1832
1833
1/2
✓ Branch 0 taken 15359538 times.
✗ Branch 1 not taken.
31108444 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
1834 15748906 int screen = scr->screen;
1835 int32_t x;
1836
1837
2/2
✓ Branch 0 taken 2771807456 times.
✓ Branch 1 taken 15748906 times.
2787556362 for(int32_t i=0; i<176; i++)
1838 {
1839 2771807456 x=scr->data[i];
1840 2771807456 auto& mini_cmb = combo_cache.minis[x];
1841
2/2
✓ Branch 0 taken 3282224 times.
✓ Branch 1 taken 2768525232 times.
2771807456 if (!mini_cmb.can_cycle)
1842 2768525232 continue;
1843
1844 3282224 newcombo const& cmb = combobuf[x];
1845
1846 //time to restart
1847
4/4
✓ Branch 0 taken 904477 times.
✓ Branch 1 taken 2377747 times.
✓ Branch 2 taken 475770 times.
✓ Branch 3 taken 428707 times.
3282224 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1848 {
1849 428707 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1850
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428707 times.
428707 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1851 428707 newdata[i] = c;
1852
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428687 times.
428707 if(!(cmb.animflags & AF_CYCLENOCSET))
1853
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428687 times.
428687 newcset[i] = cycle_under ? scr->undercset : cmb.nextcset;
1854
1855
2/2
✓ Branch 0 taken 427663 times.
✓ Branch 1 taken 1044 times.
428707 if(combobuf[c].animflags & AF_CYCLE)
1856 {
1857 1044 restartanim.insert(c);
1858 1044 }
1859 428707 }
1860 3282224 }
1861
1862 15748906 int rpos_base = (int)POS_TO_RPOS(0, region_scr_x, region_scr_y);
1863
2/2
✓ Branch 0 taken 2771807456 times.
✓ Branch 1 taken 15748906 times.
2787556362 for(int32_t i=0; i<176; i++)
1864 {
1865
2/2
✓ Branch 0 taken 428707 times.
✓ Branch 1 taken 2771378749 times.
2771807456 if(newdata[i]==-1)
1866 2771378749 continue;
1867
1868 428707 rpos_t rpos = (rpos_t)(rpos_base + i);
1869 428707 rpos_handle_t rpos_handle = {scr, screen, 0, rpos, i};
1870 428707 screen_combo_modify_preroutine(rpos_handle);
1871 428707 scr->data[i]=newdata[i];
1872
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428687 times.
428707 if(newcset[i]>-1)
1873 428687 scr->cset[i]=newcset[i];
1874 428707 screen_combo_modify_postroutine(rpos_handle);
1875
1876 428707 newdata[i]=-1;
1877 428707 newcset[i]=-1;
1878 428707 }
1879
1880 15748906 word c = scr->numFFC();
1881
2/2
✓ Branch 0 taken 15748906 times.
✓ Branch 1 taken 454715631 times.
470464537 for(word i=0; i<c; i++)
1882 {
1883 454715631 ffcdata& ffc = scr->ffcs[i];
1884 454715631 auto& mini_cmb = combo_cache.minis[ffc.data];
1885
2/2
✓ Branch 0 taken 7727 times.
✓ Branch 1 taken 454707904 times.
454715631 if (!mini_cmb.can_cycle)
1886 454707904 continue;
1887
1888 7727 newcombo const& cmb = combobuf[ffc.data];
1889
1890 //time to restart
1891
4/4
✓ Branch 0 taken 1181 times.
✓ Branch 1 taken 6546 times.
✓ Branch 2 taken 856 times.
✓ Branch 3 taken 325 times.
7727 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1892 {
1893 325 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1894
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
325 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1895 325 zc_ffc_set(ffc, c);
1896
2/2
✓ Branch 0 taken 217 times.
✓ Branch 1 taken 108 times.
325 if(!(cmb.animflags & AF_CYCLENOCSET))
1897
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 ffc.cset = cycle_under ? scr->undercset : cmb.nextcset;
1898
1899
2/2
✓ Branch 0 taken 265 times.
✓ Branch 1 taken 60 times.
325 if(combobuf[ffc.data].animflags & AF_CYCLE)
1900 {
1901 60 restartanim.insert(ffc.data);
1902 60 }
1903 325 }
1904 7727 }
1905
1906
2/2
✓ Branch 0 taken 8418399 times.
✓ Branch 1 taken 7330507 times.
15748906 if(get_qr(qr_CMBCYCLELAYERS))
1907 {
1908
2/2
✓ Branch 0 taken 43983042 times.
✓ Branch 1 taken 7330507 times.
51313549 for(int32_t j=1; j<=6; j++)
1909 {
1910 43983042 mapscr* layer_scr = get_scr_layer_valid(screen, j);
1911
2/2
✓ Branch 0 taken 13893876 times.
✓ Branch 1 taken 30089166 times.
43983042 if (!layer_scr)
1912 30089166 continue;
1913
1914
2/2
✓ Branch 0 taken 2445322176 times.
✓ Branch 1 taken 13893876 times.
2459216052 for(int32_t i=0; i<176; i++)
1915 {
1916 2445322176 x=layer_scr->data[i];
1917 2445322176 auto& mini_cmb = combo_cache.minis[x];
1918
2/2
✓ Branch 0 taken 2424344 times.
✓ Branch 1 taken 2442897832 times.
2445322176 if (!mini_cmb.can_cycle)
1919 2442897832 continue;
1920
1921 2424344 newcombo const& cmb = combobuf[x];
1922
1923 //time to restart
1924
4/4
✓ Branch 0 taken 67298 times.
✓ Branch 1 taken 2357046 times.
✓ Branch 2 taken 50626 times.
✓ Branch 3 taken 16672 times.
2424344 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1925 {
1926 16672 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1927
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16672 times.
16672 auto c = cycle_under ? layer_scr->undercombo : cmb.nextcombo;
1928 16672 newdata[i] = c;
1929
2/2
✓ Branch 0 taken 644 times.
✓ Branch 1 taken 16028 times.
16672 if(!(cmb.animflags & AF_CYCLENOCSET))
1930
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16028 times.
16028 newcset[i] = cycle_under ? layer_scr->undercset : cmb.nextcset;
1931 644 else newcset[i] = layer_scr->cset[i];
1932
1933
2/2
✓ Branch 0 taken 6689 times.
✓ Branch 1 taken 9983 times.
16672 if(combobuf[c].animflags & AF_CYCLE)
1934 {
1935 9983 restartanim.insert(c);
1936 9983 }
1937 16672 }
1938 2424344 }
1939
1940
2/2
✓ Branch 0 taken 2445322176 times.
✓ Branch 1 taken 13893876 times.
2459216052 for (int32_t i=0; i<176; i++)
1941 {
1942
2/2
✓ Branch 0 taken 2445305504 times.
✓ Branch 1 taken 16672 times.
2445322176 if(newdata[i]!=-1)
1943 {
1944 16672 layer_scr->data[i]=newdata[i];
1945
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16672 times.
16672 if(newcset[i]>-1)
1946 16672 layer_scr->cset[i]=newcset[i];
1947 16672 newdata[i]=-1;
1948 16672 newcset[i]=-1;
1949 16672 }
1950 2445322176 }
1951 13893876 }
1952 7330507 }
1953 15748906 });
1954
1955
2/2
✓ Branch 0 taken 15359538 times.
✓ Branch 1 taken 2661 times.
15362199 for (auto i : restartanim)
1956 {
1957 2661 combobuf[i].tile = combobuf[i].o_tile;
1958 2661 combobuf[i].cur_frame=0;
1959 2661 combobuf[i].aclk = 0;
1960
1/2
✓ Branch 0 taken 2661 times.
✗ Branch 1 not taken.
2661 combo_caches::drawing.refresh(i);
1961 }
1962 15359538 }
1963
1964 1426173461 bool iswater_type(int32_t type)
1965 {
1966 // return type==cOLD_WATER || type==cSWIMWARP || type==cDIVEWARP || type==cDIVEWARPB || type==cDIVEWARPC || type==cDIVEWARPD || type==cSWIMWARPB || type==cSWIMWARPC || type==cSWIMWARPD;
1967 1426173461 return (combo_class_buf[type].water!=0);
1968 }
1969
1970 bool iswater(int32_t combo)
1971 {
1972 return iswater_type(combobuf[combo].type) && !DRIEDLAKE;
1973 }
1974 5280776 int32_t iswaterexzq(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck)
1975 {
1976 5280776 return iswaterex(combo, map, screen, layer, x, y, secrets, fullcheck, LayerCheck);
1977 }
1978
1979 // (x, y) are world coordinates
1980 68239579 int32_t iswaterex_z3(int32_t combo, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
1981 {
1982
8/8
✓ Branch 0 taken 68191716 times.
✓ Branch 1 taken 47863 times.
✓ Branch 2 taken 68149856 times.
✓ Branch 3 taken 41860 times.
✓ Branch 4 taken 68080373 times.
✓ Branch 5 taken 69483 times.
✓ Branch 6 taken 63405 times.
✓ Branch 7 taken 68016968 times.
68239579 if (x<0 || x>=world_w || y<0 || y>=world_h)
1983 222611 return false;
1984
1985 68016968 return iswaterex(combo, cur_map, cur_screen, layer, x, y, secrets, fullcheck, LayerCheck, ShallowCheck, hero, out_handle);
1986 68239579 }
1987
1988 148701362 int32_t iswaterex(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
1989 {
1990 DCHECK_LAYER_NEG1_INDEX(layer);
1991 //Honestly, fullcheck is kinda useless... I made this function back when I thought it was checking the entire combo and not just a glorified x/y value.
1992 //Fullcheck makes no sense to ever be on, but hey I guess it's here in case you ever need it...
1993
1994 //Oh hey, Zoras might actually need it. Nevermind, this had a use!
1995
2/2
✓ Branch 0 taken 108784253 times.
✓ Branch 1 taken 39917109 times.
148701362 if (get_qr(qr_SMARTER_WATER))
1996 {
1997
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 108784253 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
108784253 if (DRIEDLAKE) return 0;
1998
5/6
✓ Branch 0 taken 32449722 times.
✓ Branch 1 taken 76334531 times.
✓ Branch 2 taken 6533834 times.
✓ Branch 3 taken 25915888 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6533834 times.
108784253 if (LayerCheck && (get_qr(qr_WATER_ON_LAYER_1) || get_qr(qr_WATER_ON_LAYER_2))) //LayerCheck is a bit dumber, but it lets me add this QR without having to replace all calls, again.
1999 {
2000
2/2
✓ Branch 0 taken 75576072 times.
✓ Branch 1 taken 24825875 times.
100401947 for (int32_t m = layer; m <= 1; m++)
2001 {
2002
5/6
✓ Branch 0 taken 49660184 times.
✓ Branch 1 taken 25915888 times.
✓ Branch 2 taken 24833090 times.
✓ Branch 3 taken 24827094 times.
✓ Branch 4 taken 24827094 times.
✗ Branch 5 not taken.
100403166 if (m < 0 || m == 0 && get_qr(qr_WATER_ON_LAYER_1)
2003
1/2
✓ Branch 0 taken 24827094 times.
✗ Branch 1 not taken.
49660184 || m == 1 && get_qr(qr_WATER_ON_LAYER_2))
2004 {
2005 75576072 int32_t checkwater = iswaterex(combo, map, screen, m, x, y, secrets, fullcheck, false, ShallowCheck);
2006
2/2
✓ Branch 0 taken 74486059 times.
✓ Branch 1 taken 1090013 times.
75576072 if (checkwater > 0)
2007 {
2008
2/2
✓ Branch 0 taken 1089930 times.
✓ Branch 1 taken 83 times.
1090013 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, m+1);
2009 1090013 return checkwater;
2010 }
2011 74486059 }
2012 74486059 }
2013 24825875 return 0;
2014 }
2015 else
2016 {
2017
2/2
✓ Branch 0 taken 82892009 times.
✓ Branch 1 taken 78340350 times.
161232359 for(int32_t i=(fullcheck?3:0); i>=0; i--)
2018 {
2019 82892009 int32_t tx2=((i&2)<<2)+x;
2020 82892009 int32_t ty2=((i&1)<<3)+y;
2021 82892009 int32_t b = i; //Originally b was not needed and I read off i, but then I added the boolean for fullcheck.
2022 //In which case it's just easier to change b if fullcheck is false instead of changing i and potentially screwing up the for loop.
2023
2/2
✓ Branch 0 taken 36073 times.
✓ Branch 1 taken 82855936 times.
82892009 if (!fullcheck)
2024 {
2025 82855936 tx2 = x;
2026 82855936 ty2 = y;
2027
2/2
✓ Branch 0 taken 45327683 times.
✓ Branch 1 taken 37528253 times.
82855936 if(tx2&8) b+=2;
2028
2/2
✓ Branch 0 taken 39266539 times.
✓ Branch 1 taken 43589397 times.
82855936 if(ty2&8) b+=1;
2029 82855936 }
2030
2/2
✓ Branch 0 taken 171755009 times.
✓ Branch 1 taken 80448594 times.
252203603 for (int32_t m = layer; m <= 1; m++)
2031 {
2032 171755009 newcombo const& cmb = combobuf[MAPCOMBO3(map, screen, m,tx2,ty2, true)];
2033
3/6
✓ Branch 0 taken 169567506 times.
✓ Branch 1 taken 2187503 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 169567506 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
171755009 if (hero && cmb.dive_under_level && (Hero.get_standing_z_state() <= -cmb.dive_under_level))
2034 continue; // dive under this layer
2035
2036
2/2
✓ Branch 0 taken 17728431 times.
✓ Branch 1 taken 154026578 times.
171755009 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2037 {
2038
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17728431 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17728431 if (cmb.type == cBRIDGE && !(cmb.walk&(1<<b)))
2039 {
2040 return 0;
2041 }
2042 17728431 }
2043 else
2044 {
2045
4/4
✓ Branch 0 taken 253102 times.
✓ Branch 1 taken 153773476 times.
✓ Branch 2 taken 51152 times.
✓ Branch 3 taken 201950 times.
154026578 if (cmb.type == cBRIDGE && (cmb.walk&(0x10<<b)))
2046 {
2047 201950 return 0;
2048 }
2049 }
2050
2/2
✓ Branch 0 taken 17728431 times.
✓ Branch 1 taken 153824628 times.
171553059 if (get_qr(qr_NO_SOLID_SWIM))
2051 {
2052
8/14
✓ Branch 0 taken 51152 times.
✓ Branch 1 taken 153773476 times.
✓ Branch 2 taken 51152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2241465 times.
✓ Branch 5 taken 151532011 times.
✓ Branch 6 taken 34499 times.
✓ Branch 7 taken 2206966 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 34499 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
153824628 if ((cmb.type != cBRIDGE || (!get_qr(qr_OLD_BRIDGE_COMBOS) && !(cmb.walk&(0x10<<b)))) && (cmb.walk&(1<<b)) && !((cmb.usrflags&cflag4) && cmb.type == cWATER && (cmb.walk&(0x10<<b)) && ShallowCheck))
2053 2241465 return 0;
2054 151583163 }
2055
3/6
✓ Branch 0 taken 497938 times.
✓ Branch 1 taken 168813656 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 497938 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
169311594 if (iswater_type(cmb.type) && (cmb.walk&(1<<b)) && ((cmb.usrflags&cflag3) || (cmb.usrflags&cflag4)
2056 || (hero && current_item(itype_flippers) < cmb.attribytes[0])
2057 || (hero && ((cmb.usrflags&cflag1) && !(itemsbuf[current_item_id(itype_flippers)].flags & item_flag3)))))
2058 {
2059 if (!(ShallowCheck && (cmb.walk&(1<<b)) && (cmb.usrflags&cflag4))) return 0;
2060 }
2061 169311594 }
2062
2063 80448594 bool found_land = false;
2064 80448594 bool found_water = false;
2065 ffc_handle_t water_ffc_handle;
2066 223212291 find_ffc([&](const ffc_handle_t& ffc_handle) {
2067
2/2
✓ Branch 0 taken 141976906 times.
✓ Branch 1 taken 786791 times.
142763697 if (ffcIsAt(ffc_handle, tx2, ty2))
2068 {
2069 786791 auto ty = ffc_handle.ctype();
2070
3/4
✓ Branch 0 taken 786791 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 592941 times.
✓ Branch 3 taken 193850 times.
786791 bool is_water_type = combo_class_buf[ty].water || (ShallowCheck && ty == cSHALLOWWATER);
2071
2072
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 786791 times.
786791 if (!is_water_type)
2073 {
2074 786791 found_land = true;
2075 786791 return true;
2076 }
2077 else
2078 {
2079 // A later FFC might be land, in which case the water will be ignored.
2080 if (!found_water)
2081 {
2082 water_ffc_handle = ffc_handle;
2083 found_water = true;
2084 }
2085 }
2086 }
2087
2088 141976906 return false;
2089 142763697 });
2090
2091
2/2
✓ Branch 0 taken 79661803 times.
✓ Branch 1 taken 786791 times.
80448594 if (found_land) return 0;
2092
2093
3/4
✓ Branch 0 taken 79638159 times.
✓ Branch 1 taken 23644 times.
✓ Branch 2 taken 79638159 times.
✗ Branch 3 not taken.
79661803 if (!i && found_water)
2094 {
2095 if (out_handle) *out_handle = water_ffc_handle;
2096 return water_ffc_handle.data();
2097 }
2098
2099 79661803 int32_t checkcombo = MAPCOMBO3(map, screen, layer, tx2, ty2, secrets);
2100
2/2
✓ Branch 0 taken 79617309 times.
✓ Branch 1 taken 44494 times.
79661803 if (!(combobuf[checkcombo].walk&(1<<(b+4)))) return 0;
2101
7/12
✓ Branch 0 taken 79187287 times.
✓ Branch 1 taken 430022 times.
✓ Branch 2 taken 17015356 times.
✓ Branch 3 taken 62171931 times.
✓ Branch 4 taken 16190486 times.
✓ Branch 5 taken 824870 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16190486 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
79617309 if (iswater_type(combobuf[checkcombo].type)||(ShallowCheck && (combobuf[checkcombo].type == cSHALLOWWATER || (iswater_type(combobuf[checkcombo].type) && (combobuf[checkcombo].walk&(1<<b)) && (combobuf[checkcombo].usrflags&cflag4)))))
2102 {
2103
2/2
✓ Branch 0 taken 1577 times.
✓ Branch 1 taken 1253315 times.
1254892 if (i == 0)
2104 {
2105
2/2
✓ Branch 0 taken 1253306 times.
✓ Branch 1 taken 9 times.
1253315 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(tx2, ty2, layer+1);
2106 1253315 return checkcombo;
2107 }
2108 1577 }
2109 78363994 }
2110 78340350 return 0;
2111 }
2112 }
2113 else
2114 {
2115 39917109 int32_t b = 0;
2116
2/2
✓ Branch 0 taken 20704060 times.
✓ Branch 1 taken 19213049 times.
39917109 if(x&8) b+=2;
2117
2/2
✓ Branch 0 taken 15524133 times.
✓ Branch 1 taken 24392976 times.
39917109 if(y&8) b+=1;
2118
1/2
✓ Branch 0 taken 39917109 times.
✗ Branch 1 not taken.
39917109 if (get_qr(qr_NO_SOLID_SWIM))
2119 {
2120 if (combobuf[combo].walk&(1<<b))
2121 {
2122 return 0;
2123 }
2124 }
2125
1/2
✓ Branch 0 taken 39917109 times.
✗ Branch 1 not taken.
39917109 if (!(combobuf[combo].walk&(1<<(b+4)))) return 0;
2126
8/8
✓ Branch 0 taken 38150901 times.
✓ Branch 1 taken 1766208 times.
✓ Branch 2 taken 167945 times.
✓ Branch 3 taken 37982956 times.
✓ Branch 4 taken 2129 times.
✓ Branch 5 taken 1778552 times.
✓ Branch 6 taken 163774 times.
✓ Branch 7 taken 165477 times.
39917109 if((iswater_type(combobuf[combo].type) || (ShallowCheck && combobuf[combo].type == cSHALLOWWATER)) && !DRIEDLAKE)
2127 {
2128
2/2
✓ Branch 0 taken 1943999 times.
✓ Branch 1 taken 30 times.
1944029 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, 0); //NOTE: This is only correct assuming 'combo' is 'MAPCOMBO(x,y)'
2129 1944029 return combo;
2130 }
2131 38146730 return 0;
2132 }
2133 148875012 }
2134
2135 354 bool isdamage_type(int32_t type)
2136 {
2137
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 28 times.
354 switch(type)
2138 {
2139 case cDAMAGE1: case cDAMAGE2: case cDAMAGE3: case cDAMAGE4:
2140 case cDAMAGE5: case cDAMAGE6: case cDAMAGE7:
2141 28 return true;
2142 }
2143 326 return false;
2144 354 }
2145
2146 2230859668 bool ispitfall_type(int32_t type)
2147 {
2148 2230859668 return combo_class_buf[type].pit != 0;
2149 }
2150
2151 2230859668 bool ispitfall(int32_t combo)
2152 {
2153 2230859668 return ispitfall_type(combobuf[combo].type);
2154 }
2155
2156 138854161 bool ispitfall(int32_t x, int32_t y)
2157 {
2158
2/2
✓ Branch 0 taken 1303540 times.
✓ Branch 1 taken 137550621 times.
138854161 if(int32_t c = MAPFFCOMBO(x,y))
2159 {
2160 1303540 return ispitfall(c) ? true : false;
2161 }
2162 137550621 int32_t c = MAPCOMBOL(2,x,y);
2163
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 137550544 times.
137550621 if(ispitfall(c)) return true;
2164
2/2
✓ Branch 0 taken 122656443 times.
✓ Branch 1 taken 14894101 times.
137550544 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2165 {
2166
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 122656443 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
122656443 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return false;
2167 122656443 }
2168 else
2169 {
2170
3/4
✓ Branch 0 taken 16383 times.
✓ Branch 1 taken 14877718 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16383 times.
14894101 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return false;
2171 }
2172 137534161 c = MAPCOMBOL(1,x,y);
2173
2/2
✓ Branch 0 taken 19968 times.
✓ Branch 1 taken 137514193 times.
137534161 if(ispitfall(c)) return true;
2174
2175
2/2
✓ Branch 0 taken 122656443 times.
✓ Branch 1 taken 14857750 times.
137514193 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2176 {
2177
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 122656443 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
122656443 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return false;
2178 122656443 }
2179 else
2180 {
2181
4/4
✓ Branch 0 taken 16533 times.
✓ Branch 1 taken 14841217 times.
✓ Branch 2 taken 12238 times.
✓ Branch 3 taken 4295 times.
14857750 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return false;
2182 }
2183 137501955 c = MAPCOMBO(x,y);
2184
2/2
✓ Branch 0 taken 59028 times.
✓ Branch 1 taken 137442927 times.
137501955 if(ispitfall(c)) return true;
2185 137442927 return false;
2186 138854161 }
2187
2188 612087215 int32_t getpitfall(int32_t x, int32_t y) //Return the highest-layer active pit combo at the given position
2189 {
2190
2/2
✓ Branch 0 taken 9485176 times.
✓ Branch 1 taken 602602039 times.
612087215 if(int32_t c = MAPFFCOMBO(x,y))
2191 {
2192
2/2
✓ Branch 0 taken 845 times.
✓ Branch 1 taken 9484331 times.
9485176 return ispitfall(c) ? c : 0;
2193 }
2194 602602039 int32_t c = MAPCOMBOL(2,x,y);
2195
2/2
✓ Branch 0 taken 1362 times.
✓ Branch 1 taken 602600677 times.
602602039 if(ispitfall(c)) return c;
2196
2197
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 69878192 times.
602600677 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2198 {
2199
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return 0;
2200 532722485 }
2201 else
2202 {
2203
3/4
✓ Branch 0 taken 81755 times.
✓ Branch 1 taken 69796437 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 81755 times.
69878192 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return 0;
2204 }
2205 602518922 c = MAPCOMBOL(1,x,y);
2206
2/2
✓ Branch 0 taken 25192 times.
✓ Branch 1 taken 602493730 times.
602518922 if(ispitfall(c)) return c;
2207
2208
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 69771245 times.
602493730 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2209 {
2210
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return 0;
2211 532722485 }
2212 else
2213 {
2214
4/4
✓ Branch 0 taken 171385 times.
✓ Branch 1 taken 69599860 times.
✓ Branch 2 taken 130757 times.
✓ Branch 3 taken 40628 times.
69771245 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return 0;
2215 }
2216 602362973 c = MAPCOMBO(x,y);
2217
2/2
✓ Branch 0 taken 200737 times.
✓ Branch 1 taken 602162236 times.
602362973 if(ispitfall(c)) return c;
2218 602162236 return 0;
2219 612087215 }
2220 99 optional<combined_handle_t> get_pitfall_handle(int32_t x, int32_t y) //Return the highest-layer active pit combo handle at the given position
2221 {
2222
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 98 times.
99 if(int32_t c = MAPFFCOMBO(x,y))
2223 {
2224
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 return ispitfall(c) ? getFFCAt(x,y) : nullopt;
2225 }
2226 98 int32_t c = MAPCOMBOL(2,x,y);
2227
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 97 times.
98 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 2);
2228
2229
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 91 times.
97 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2230 {
2231
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1))
2232 return nullopt;
2233 6 }
2234 else
2235 {
2236
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
91 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1))
2237 return nullopt;
2238 }
2239 97 c = MAPCOMBOL(1,x,y);
2240
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 85 times.
97 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 1);
2241
2242
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 79 times.
85 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2243 {
2244
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0))
2245 return nullopt;
2246 6 }
2247 else
2248 {
2249
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 79 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
79 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0))
2250 return nullopt;
2251 }
2252 85 c = MAPCOMBO(x,y);
2253
1/2
✓ Branch 0 taken 85 times.
✗ Branch 1 not taken.
85 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 0);
2254 return nullopt;
2255 99 }
2256 11916027 bool check_icy(newcombo const& cmb, int type)
2257 {
2258
2/2
✓ Branch 0 taken 11915862 times.
✓ Branch 1 taken 165 times.
11916027 if(cmb.type != cICY)
2259 11915862 return false;
2260
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 165 times.
165 switch(type)
2261 {
2262 case ICY_BLOCK:
2263 return cmb.usrflags&cflag1;
2264 case ICY_PLAYER:
2265 165 return cmb.usrflags&cflag2;
2266 }
2267 return false;
2268 11916027 }
2269 3977959 int get_icy(int x, int y, int type)
2270 {
2271 3977959 int32_t c = MAPCOMBOL(2,x,y);
2272
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3977959 times.
3977959 if(check_icy(combobuf[c], type)) return c;
2273
2274 3977959 int screen = get_screen_for_world_xy(x, y);
2275
2276 3977959 mapscr* scr = get_scr_layer_valid(screen, 2);
2277
2/2
✓ Branch 0 taken 33173 times.
✓ Branch 1 taken 3944786 times.
3977959 if (scr)
2278 {
2279
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 3944270 times.
3944786 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2280 {
2281
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 516 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
516 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2282 516 }
2283 else
2284 {
2285
3/4
✓ Branch 0 taken 6663 times.
✓ Branch 1 taken 3937607 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6663 times.
3944270 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2286 }
2287 3938123 }
2288 3971296 c = MAPCOMBOL(1,x,y);
2289
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3971296 times.
3971296 if(check_icy(combobuf[c], type)) return c;
2290
2291 3971296 scr = get_scr_layer_valid(screen, 1);
2292
2/2
✓ Branch 0 taken 15312 times.
✓ Branch 1 taken 3955984 times.
3971296 if (scr)
2293 {
2294
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 3954050 times.
3955984 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2295 {
2296
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1934 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1934 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2297 1934 }
2298 else
2299 {
2300
3/4
✓ Branch 0 taken 4689 times.
✓ Branch 1 taken 3949361 times.
✓ Branch 2 taken 4689 times.
✗ Branch 3 not taken.
3954050 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2301 }
2302 3951295 }
2303 3966607 c = MAPCOMBO(x,y);
2304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3966607 times.
3966607 if(check_icy(combobuf[c], type)) return c;
2305 3966607 return 0;
2306 3977959 }
2307
2308 13260927 static bool checkSV(int32_t x, int32_t y, int32_t flag)
2309 {
2310
8/8
✓ Branch 0 taken 13254129 times.
✓ Branch 1 taken 6798 times.
✓ Branch 2 taken 13245263 times.
✓ Branch 3 taken 8866 times.
✓ Branch 4 taken 13233631 times.
✓ Branch 5 taken 11632 times.
✓ Branch 6 taken 434748 times.
✓ Branch 7 taken 12798883 times.
13260927 if(x<0 || x>=world_w || y<0 || y>=world_h)
2311 462044 return false;
2312
2313 12798883 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
2314
2/4
✓ Branch 0 taken 12798883 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12798883 times.
12798883 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2315 return true;
2316
2317 12798883 change_rpos_handle_layer(rpos_handle, 1);
2318
2/2
✓ Branch 0 taken 7571606 times.
✓ Branch 1 taken 5227277 times.
12798883 if (rpos_handle.scr->is_valid())
2319
3/4
✓ Branch 0 taken 5227277 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3279 times.
✓ Branch 3 taken 5223998 times.
5227277 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2320 3279 return true;
2321
2322 12795604 change_rpos_handle_layer(rpos_handle, 2);
2323
2/2
✓ Branch 0 taken 10855408 times.
✓ Branch 1 taken 1940196 times.
12795604 if (rpos_handle.scr->is_valid())
2324
3/4
✓ Branch 0 taken 1940196 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 1940115 times.
1940196 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2325 81 return true;
2326
2327 12795523 return false;
2328 13260927 }
2329
2330 6694646 bool isSVLadder(int32_t x, int32_t y)
2331 {
2332 6694646 return checkSV(x, y, mfSIDEVIEWLADDER);
2333 }
2334
2335 6566281 bool isSVPlatform(int32_t x, int32_t y)
2336 {
2337 6566281 return checkSV(x, y, mfSIDEVIEWPLATFORM);
2338 }
2339
2340 6566281 bool checkSVLadderPlatform(int32_t x, int32_t y)
2341 {
2342
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6566281 times.
✓ Branch 2 taken 6564443 times.
✓ Branch 3 taken 1838 times.
6566281 return isSVPlatform(x,y) || (isSVLadder(x,y) && !isSVLadder(x,y-16));
2343 }
2344
2345 4206 bool isstepable(int32_t combo) //can use ladder on it
2346 {
2347
2/2
✓ Branch 0 taken 4200 times.
✓ Branch 1 taken 6 times.
4206 if(combo_class_buf[combobuf[combo].type].ladder_pass) return true;
2348
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(combo_class_buf[combobuf[combo].type].pit)
2349 {
2350 if(combobuf[combo].usrflags&cflag4)
2351 {
2352 int32_t ldrid = current_item_id(itype_ladder);
2353 return (ldrid > -1 && itemsbuf[ldrid].flags & item_flag1);
2354 }
2355 }
2356 6 return false;
2357 4206 }
2358
2359 33016 bool isHSGrabbable(newcombo const& cmb)
2360 {
2361
2/2
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 32639 times.
33016 if(cmb.type == cHSGRAB) return true;
2362 32639 return cmb.genflags & cflag1;
2363 33016 }
2364
2365 954 bool isSwitchHookable(newcombo const& cmb)
2366 {
2367
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 822 times.
954 if(cmb.type == cSWITCHHOOK) return true;
2368 822 return cmb.genflags & cflag2;
2369 954 }
2370
2371 62207 bool check_hshot(int32_t layer, int32_t x, int32_t y, bool switchhook, rpos_t *out_rpos, ffcdata **out_ffc)
2372 {
2373 62207 rpos_t cpos = rpos_t::None;
2374
2/2
✓ Branch 0 taken 65056 times.
✓ Branch 1 taken 127263 times.
62207 if(out_rpos)
2375 {
2376 127263 int32_t id = MAPCOMBO2(layer-1,x,y);
2377
2/2
✓ Branch 0 taken 29204 times.
✓ Branch 1 taken 98059 times.
127263 if(id > 0)
2378 {
2379 98059 newcombo const& cmb = combobuf[id];
2380
4/4
✓ Branch 0 taken 32974 times.
✓ Branch 1 taken 65085 times.
✓ Branch 2 taken 32528 times.
✓ Branch 3 taken 32557 times.
98059 cpos = (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb)) ? COMBOPOS_REGION(x,y) : rpos_t::None;
2381 33003 }
2382 62207 }
2383
2384 127263 ffcdata* ffc = nullptr;
2385
4/4
✓ Branch 0 taken 28531 times.
✓ Branch 1 taken 98732 times.
✓ Branch 2 taken 24996 times.
✓ Branch 3 taken 3535 times.
127263 if (out_ffc && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2386 {
2387 10645 for_some_ffcs([&](const ffc_handle_t& ffc_handle) {
2388
2/2
✓ Branch 0 taken 6995 times.
✓ Branch 1 taken 115 times.
7110 if (ffcIsAt(ffc_handle, x, y))
2389 {
2390 115 auto& cmb = ffc_handle.combo();
2391
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 37 times.
✓ Branch 3 taken 36 times.
115 if (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb))
2392 {
2393 79 ffc = ffc_handle.ffc;
2394 79 return false;
2395 }
2396 36 }
2397 7031 return true;
2398 7038 });
2399 3535 }
2400
2401
4/4
✓ Branch 0 taken 62207 times.
✓ Branch 1 taken 65056 times.
✓ Branch 2 taken 446 times.
✓ Branch 3 taken 61761 times.
127263 if (out_rpos && cpos != rpos_t::None) *out_rpos = cpos;
2402
4/4
✓ Branch 0 taken 28531 times.
✓ Branch 1 taken 98732 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 28524 times.
127263 if (out_ffc && ffc) *out_ffc = ffc;
2403
2/2
✓ Branch 0 taken 65502 times.
✓ Branch 1 taken 61761 times.
127263 return (cpos != rpos_t::None || ffc);
2404 }
2405
2406 5199 bool ishookshottable(int32_t bx, int32_t by)
2407 {
2408
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5199 times.
5199 if(!_walkflag(bx,by,1))
2409 return true;
2410
2411
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5191 times.
5199 if (collide_object(bx, by, 1, 1))
2412 8 return false;
2413
2414 5191 bool ret = true;
2415
2/2
✓ Branch 0 taken 15573 times.
✓ Branch 1 taken 1904 times.
17477 for(int32_t i=2; i>=0; i--)
2416 {
2417 15573 int32_t c = MAPCOMBO2(i-1,bx,by);
2418 15573 int32_t t = combobuf[c].type;
2419
2420
6/6
✓ Branch 0 taken 5191 times.
✓ Branch 1 taken 10382 times.
✓ Branch 2 taken 3857 times.
✓ Branch 3 taken 1334 times.
✓ Branch 4 taken 1904 times.
✓ Branch 5 taken 1953 times.
15573 if(i == 0 && (t == cHOOKSHOTONLY || t == cLADDERHOOKSHOT)) return true;
2421
2422
3/4
✓ Branch 0 taken 11333 times.
✓ Branch 1 taken 953 times.
✓ Branch 2 taken 953 times.
✗ Branch 3 not taken.
13239 bool dried = (iswater_type(t) && DRIEDLAKE);
2423
2424 12286 int32_t b=1;
2425
2426
2/2
✓ Branch 0 taken 6112 times.
✓ Branch 1 taken 6174 times.
12286 if(bx&8) b<<=2;
2427
2428
2/2
✓ Branch 0 taken 3853 times.
✓ Branch 1 taken 8433 times.
12286 if(by&8) b<<=1;
2429
2430
7/8
✓ Branch 0 taken 2098 times.
✓ Branch 1 taken 10188 times.
✓ Branch 2 taken 2098 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1115 times.
✓ Branch 5 taken 983 times.
✓ Branch 6 taken 75 times.
✓ Branch 7 taken 908 times.
12286 if(combobuf[c].walk&b && !dried && !(combo_class_buf[t].ladder_pass && t!=cLADDERONLY) && t!=cHOOKSHOTONLY)
2431 908 ret = false;
2432 12286 }
2433
2434 1904 return ret;
2435 5199 }
2436
2437 11108 bool reveal_hidden_stairs(mapscr *s, int32_t screen, bool redraw)
2438 {
2439
4/4
✓ Branch 0 taken 10529 times.
✓ Branch 1 taken 579 times.
✓ Branch 2 taken 10529 times.
✓ Branch 3 taken 579 times.
11108 if((s->stairx || s->stairy) && s->secretcombo[sSTAIRS])
2440 {
2441 579 int pos = COMBOPOS(s->stairx,s->stairy);
2442 579 s->data[pos] = s->secretcombo[sSTAIRS];
2443 579 s->cset[pos] = s->secretcset[sSTAIRS];
2444 579 s->sflag[pos] = s->secretflag[sSTAIRS];
2445
2446
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 323 times.
579 if (redraw)
2447 {
2448 768 auto [x, y] = translate_screen_coordinates_to_world(screen, s->stairx, s->stairy);
2449 768 putcombo(scrollbuf,x,y,s->data[pos],s->cset[pos]);
2450 256 }
2451
2452 579 return true;
2453 }
2454
2455 10529 return false;
2456 11108 }
2457
2458 52906 screen_handles_t create_screen_handles_one(mapscr* base_scr)
2459 {
2460 DCHECK(base_scr->is_valid());
2461
2462 52906 screen_handles_t screen_handles{};
2463 52906 screen_handles[0] = {base_scr, base_scr, base_scr->screen, 0};
2464 52906 return screen_handles;
2465 }
2466
2467 58578202 screen_handles_t create_screen_handles(mapscr* base_scr)
2468 {
2469 DCHECK(get_scr(base_scr->screen) == base_scr);
2470 DCHECK(base_scr->is_valid());
2471
2472 58578202 int screen = base_scr->screen;
2473 screen_handles_t screen_handles;
2474 58578202 screen_handles[0] = {base_scr, base_scr, screen, 0};
2475
2/2
✓ Branch 0 taken 351469212 times.
✓ Branch 1 taken 58578202 times.
410047414 for (int i = 1; i <= 6; i++)
2476 351469212 screen_handles[i] = {base_scr, get_scr_layer_valid(screen, i), screen, i};
2477 58578202 return screen_handles;
2478 }
2479
2480 113471 bool remove_screenstatecombos2(const screen_handles_t& screen_handles, bool do_layers, int32_t what1, int32_t what2)
2481 {
2482 113471 mapscr* scr = screen_handles[0].scr;
2483 113471 bool didit=false;
2484
2485
2/2
✓ Branch 0 taken 113471 times.
✓ Branch 1 taken 19970896 times.
20084367 for(int32_t i=0; i<176; i++)
2486 {
2487 19970896 newcombo const& cmb = combobuf[scr->data[i]];
2488
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 19970570 times.
19970896 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2489
4/4
✓ Branch 0 taken 19968994 times.
✓ Branch 1 taken 1576 times.
✓ Branch 2 taken 1134 times.
✓ Branch 3 taken 19967860 times.
19970570 if((cmb.type == what1) || (cmb.type== what2))
2490 {
2491 2710 scr->data[i]++;
2492 2710 didit=true;
2493 2710 }
2494 19970570 }
2495
2496
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 113379 times.
113471 if (do_layers)
2497 {
2498
2/2
✓ Branch 0 taken 680274 times.
✓ Branch 1 taken 113379 times.
793653 for(int32_t j=1; j<=6; j++)
2499 {
2500 680274 mapscr* layer_scr = screen_handles[j].scr;
2501
2/2
✓ Branch 0 taken 195881 times.
✓ Branch 1 taken 484393 times.
680274 if (!layer_scr) continue;
2502
2503
2/2
✓ Branch 0 taken 34475056 times.
✓ Branch 1 taken 195881 times.
34670937 for(int32_t i=0; i<176; i++)
2504 {
2505 34475056 newcombo const& cmb = combobuf[layer_scr->data[i]];
2506
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34475056 times.
34475056 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2507
4/4
✓ Branch 0 taken 34474741 times.
✓ Branch 1 taken 315 times.
✓ Branch 2 taken 319 times.
✓ Branch 3 taken 34474422 times.
34475056 if((cmb.type== what1) || (cmb.type== what2))
2508 {
2509 634 layer_scr->data[i]++;
2510 634 didit=true;
2511 634 }
2512 34475056 }
2513 195881 }
2514 113379 }
2515
2516 // 'do_layers' also means that this is called on an active temp screen, so update its ffcs.
2517
3/4
✓ Branch 0 taken 27675 times.
✓ Branch 1 taken 85796 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27675 times.
113471 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && do_layers)
2518 {
2519 27675 word c = scr->numFFC();
2520
2/2
✓ Branch 0 taken 80883 times.
✓ Branch 1 taken 27675 times.
108558 for(word i=0; i<c; i++)
2521 {
2522 80883 ffcdata* ffc = &scr->ffcs[i];
2523 80883 newcombo const& cmb = combobuf[ffc->data];
2524
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80883 times.
80883 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2525
2/4
✓ Branch 0 taken 80883 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 80883 times.
80883 if((cmb.type== what1) || (cmb.type== what2))
2526 {
2527 zc_ffc_modify(*ffc, 1);
2528 didit=true;
2529 }
2530 80883 }
2531 27675 }
2532
2533 113471 return didit;
2534 }
2535
2536 14 bool remove_xstatecombos(const screen_handles_t& screen_handles, byte xflag, bool triggers)
2537 {
2538 14 int screen = screen_handles[0].scr->screen;
2539
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2540 14 return remove_xstatecombos_mi(screen_handles, mi, xflag, triggers);
2541 }
2542 488421454 bool remove_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, byte xflag, bool triggers)
2543 {
2544 488421454 bool didit=false;
2545
2/2
✓ Branch 0 taken 488380493 times.
✓ Branch 1 taken 40961 times.
488421454 if(!getxmapflag_mi(mi, 1<<xflag)) return false;
2546
2547 40961 mapscr* s = screen_handles[0].scr;
2548 40961 int screen = s->screen;
2549 40961 bool is_active_screen = is_in_current_region(s);
2550
2551 34122305 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2552
4/4
✓ Branch 0 taken 49456 times.
✓ Branch 1 taken 34031888 times.
✓ Branch 2 taken 1891 times.
✓ Branch 3 taken 34079453 times.
34081344 if(triggers && force_ex_trigger_any(rpos_handle, xflag))
2553 1891 didit = true;
2554
2/2
✓ Branch 0 taken 64673 times.
✓ Branch 1 taken 34014780 times.
34079453 else switch (rpos_handle.ctype())
2555 {
2556 case cLOCKBLOCK: case cLOCKBLOCK2:
2557 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2558 case cCHEST: case cCHEST2:
2559 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2560 case cBOSSCHEST: case cBOSSCHEST2:
2561 {
2562 64673 auto& cmb = rpos_handle.combo();
2563
2/2
✓ Branch 0 taken 62059 times.
✓ Branch 1 taken 2614 times.
64673 if(!(cmb.usrflags&cflag16)) return; //custom state instead of normal state
2564
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 62030 times.
62059 if(cmb.attribytes[5] == xflag)
2565 {
2566 29 rpos_handle.increment_data();
2567 29 didit=true;
2568 29 }
2569 62059 break;
2570 }
2571 }
2572 34081344 });
2573
2574
4/4
✓ Branch 0 taken 40889 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 31269 times.
✓ Branch 3 taken 9620 times.
40961 if (is_active_screen && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2575 {
2576 31269 word c = s->numFFC();
2577 31269 int screen_index_offset = get_region_screen_offset(screen);
2578
2/2
✓ Branch 0 taken 65746 times.
✓ Branch 1 taken 31269 times.
97015 for (uint8_t i = 0; i < c; i++)
2579 {
2580 65746 auto ffc_handle = *s->getFFCHandle(i, screen_index_offset);
2581 65746 auto& cmb = ffc_handle.combo();
2582
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 65746 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 65730 times.
65746 if(triggers && force_ex_trigger_any(ffc_handle, xflag))
2583 16 didit = true;
2584
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65730 times.
65730 else switch(cmb.type)
2585 {
2586 case cLOCKBLOCK: case cLOCKBLOCK2:
2587 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2588 case cCHEST: case cCHEST2:
2589 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2590 case cBOSSCHEST: case cBOSSCHEST2:
2591 {
2592 if(!(cmb.usrflags&cflag16)) continue; //custom state instead of normal state
2593 if(cmb.attribytes[5] == xflag)
2594 {
2595 zc_ffc_modify(*ffc_handle.ffc, 1);
2596 didit=true;
2597 }
2598 break;
2599 }
2600 }
2601 65746 }
2602 31269 }
2603
2604 40961 return didit;
2605 488421454 }
2606
2607 15210041 void clear_xstatecombos(const screen_handles_t& screen_handles, bool triggers)
2608 {
2609 15210041 int screen = screen_handles[0].screen;
2610
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14822208 times.
15210041 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2611 15210041 clear_xstatecombos_mi(screen_handles, mi, triggers);
2612 15210041 }
2613
2614 15263170 void clear_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2615 {
2616
2/2
✓ Branch 0 taken 488421440 times.
✓ Branch 1 taken 15263170 times.
503684610 for (int q = 0; q < 32; ++q)
2617 {
2618 488421440 remove_xstatecombos_mi(screen_handles, mi, q, triggers);
2619 488421440 }
2620 15263170 }
2621
2622 bool remove_xdoors(const screen_handles_t& screen_handles, uint dir, uint ind, bool triggers)
2623 {
2624 int screen = screen_handles[0].screen;
2625 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2626 return remove_xdoors_mi(screen_handles, mi, dir, ind, triggers);
2627 }
2628 488421440 bool remove_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, uint dir, uint ind, bool triggers)
2629 {
2630 488421440 bool didit=false;
2631
2/2
✓ Branch 0 taken 488420127 times.
✓ Branch 1 taken 1313 times.
488421440 if (!getxdoor_mi(mi, dir, ind)) return false;
2632
2633 1313 mapscr* scr = screen_handles[0].scr;
2634 1313 int screen = scr->screen;
2635 1313 bool is_active_screen = is_in_current_region(scr);
2636
2637 925665 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2638
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 924352 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 924341 times.
924352 if (triggers && force_ex_door_trigger_any(rpos_handle, dir, ind))
2639 11 didit = true;
2640 else; //future door combo types?
2641 924352 });
2642
2643
2/4
✓ Branch 0 taken 1313 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1313 times.
✗ Branch 3 not taken.
1313 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && is_active_screen)
2644 {
2645 1313 word c = scr->numFFC();
2646 1313 int screen_index_offset = get_region_screen_offset(screen);
2647
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1313 times.
1313 for (uint8_t i = 0; i < c; i++)
2648 {
2649 auto ffc_handle = *scr->getFFCHandle(i, screen_index_offset);
2650 if (triggers && force_ex_door_trigger_any(ffc_handle, dir, ind))
2651 didit = true;
2652 else; //future door combo types?
2653 }
2654 1313 }
2655
2656 1313 return didit;
2657 488421440 }
2658
2659 15210041 void clear_xdoors(const screen_handles_t& screen_handles, bool triggers)
2660 {
2661 15210041 int screen = screen_handles[0].screen;
2662
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14822208 times.
15210041 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2663 15210041 return clear_xdoors_mi(screen_handles, mi, triggers);
2664 }
2665
2666 15263170 void clear_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2667 {
2668
2/2
✓ Branch 0 taken 61052680 times.
✓ Branch 1 taken 15263170 times.
76315850 for (int dir = 0; dir < 4; ++dir)
2669
2/2
✓ Branch 0 taken 488421440 times.
✓ Branch 1 taken 61052680 times.
549474120 for (int q = 0; q < 8; ++q)
2670 549474120 remove_xdoors_mi(screen_handles, mi, dir, q, triggers);
2671 15263170 }
2672
2673 885 bool remove_lockblocks(const screen_handles_t& screen_handles)
2674 {
2675 885 return remove_screenstatecombos2(screen_handles, true, cLOCKBLOCK, cLOCKBLOCK2);
2676 }
2677
2678 139 bool remove_bosslockblocks(const screen_handles_t& screen_handles)
2679 {
2680 139 return remove_screenstatecombos2(screen_handles, true, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
2681 }
2682
2683 83659 bool remove_chests(const screen_handles_t& screen_handles)
2684 {
2685 83659 return remove_screenstatecombos2(screen_handles, true, cCHEST, cCHEST2);
2686 }
2687
2688 2484 bool remove_lockedchests(const screen_handles_t& screen_handles)
2689 {
2690 2484 return remove_screenstatecombos2(screen_handles, true, cLOCKEDCHEST, cLOCKEDCHEST2);
2691 }
2692
2693 26212 bool remove_bosschests(const screen_handles_t& screen_handles)
2694 {
2695 26212 return remove_screenstatecombos2(screen_handles, true, cBOSSCHEST, cBOSSCHEST2);
2696 }
2697
2698 1418795 void delete_fireball_shooter(const rpos_handle_t& rpos_handle)
2699 {
2700 1418795 int32_t ct=rpos_handle.ctype();
2701
2702
6/6
✓ Branch 0 taken 1418175 times.
✓ Branch 1 taken 620 times.
✓ Branch 2 taken 1417923 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 1417815 times.
✓ Branch 5 taken 108 times.
1418795 if(ct!=cL_STATUE && ct!=cR_STATUE && ct!=cC_STATUE)
2703 1417815 return;
2704
2705 2465 auto [cx, cy] = rpos_handle.xy();
2706
3/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 620 times.
✓ Branch 3 taken 108 times.
980 switch(ct)
2707 {
2708 case cL_STATUE:
2709 620 cx += 4;
2710 620 cy += 7;
2711 620 break;
2712
2713 case cR_STATUE:
2714 252 cx -= 8;
2715 252 cy -= 1;
2716 252 break;
2717
2718 case cC_STATUE:
2719 108 break;
2720 }
2721
2722
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 1485 times.
2465 for(int32_t j=0; j<guys.Count(); j++)
2723 {
2724 // Finds the smallest enemy ID
2725
9/10
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 1086 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 53 times.
✓ Branch 8 taken 346 times.
✗ Branch 9 not taken.
2970 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy)&&(guysbuf[(guys.spr(j)->id)&0xFFF].flags & guy_fire))
2726 {
2727 346 guys.del(j);
2728 346 }
2729 1485 }
2730 1418795 }
2731
2732 45 static int32_t findtrigger(int32_t screen)
2733 {
2734 45 int32_t checkflag=0;
2735 45 int32_t ret = 0;
2736
2737 mapscr* screens[7];
2738
2/2
✓ Branch 0 taken 315 times.
✓ Branch 1 taken 45 times.
360 for (int32_t j = 0; j <= 6; j++)
2739 {
2740 315 screens[j] = get_scr_layer_valid(screen, j);
2741 315 }
2742
2743 45 bool sflag = false;
2744
2/2
✓ Branch 0 taken 7920 times.
✓ Branch 1 taken 45 times.
7965 for(word j=0; j<176; j++)
2745 {
2746
2/2
✓ Branch 0 taken 87648 times.
✓ Branch 1 taken 7920 times.
95568 for(int32_t layer = -1; layer < 6; ++layer)
2747 {
2748 87648 mapscr* scr = screens[layer+1];
2749
2/2
✓ Branch 0 taken 64416 times.
✓ Branch 1 taken 23232 times.
87648 if (!scr) continue;
2750
2751
2/2
✓ Branch 0 taken 32208 times.
✓ Branch 1 taken 32208 times.
64416 if(sflag)
2752 32208 checkflag = scr->sflag[j];
2753 else
2754 32208 checkflag = combobuf[scr->data[j]].flag;
2755 64416 sflag = !sflag;
2756
2/2
✓ Branch 0 taken 32208 times.
✓ Branch 1 taken 32208 times.
64416 if (sflag) --layer;
2757
2758
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 64374 times.
64416 switch(checkflag)
2759 {
2760 case mfANYFIRE:
2761 case mfSTRONGFIRE:
2762 case mfMAGICFIRE:
2763 case mfDIVINEFIRE:
2764 case mfARROW:
2765 case mfSARROW:
2766 case mfGARROW:
2767 case mfSBOMB:
2768 case mfBOMB:
2769 case mfBRANG:
2770 case mfMBRANG:
2771 case mfFBRANG:
2772 case mfWANDMAGIC:
2773 case mfREFMAGIC:
2774 case mfREFFIREBALL:
2775 case mfSWORD:
2776 case mfWSWORD:
2777 case mfMSWORD:
2778 case mfXSWORD:
2779 case mfSWORDBEAM:
2780 case mfWSWORDBEAM:
2781 case mfMSWORDBEAM:
2782 case mfXSWORDBEAM:
2783 case mfHOOKSHOT:
2784 case mfWAND:
2785 case mfHAMMER:
2786 case mfSTRIKE:
2787 42 ret += 1;
2788 42 break;
2789 }
2790 64416 }
2791 7920 }
2792
2793 45 return ret;
2794 }
2795
2796 12340 static void log_trigger_secret_reason(TriggerSource source)
2797 {
2798
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11888 times.
12340 if (source == TriggerSource::Singular)
2799 {
2800 452 Z_eventlog("Restricted Screen Secrets triggered\n");
2801 452 }
2802 else
2803 {
2804 11888 const char* source_str = "";
2805
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7297 times.
✓ Branch 3 taken 897 times.
✓ Branch 4 taken 3114 times.
✓ Branch 5 taken 500 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 75 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
11888 switch (source)
2806 {
2807 case TriggerSource::Singular: break;
2808 7297 case TriggerSource::Unspecified: source_str = "unspecified means"; break;
2809 897 case TriggerSource::EnemiesScreenFlag: source_str = "the 'Enemies->Secret' screen flag"; break;
2810 3114 case TriggerSource::SecretsScreenState: source_str = "the 'Secrets' screen state"; break;
2811 500 case TriggerSource::Script: source_str = "a script"; break;
2812 1 case TriggerSource::ItemsSecret: source_str = "Items->Secrets"; break;
2813 75 case TriggerSource::GenericCombo: source_str = "Generic Combo"; break;
2814 4 case TriggerSource::LightTrigger: source_str = "Light Triggers"; break;
2815 case TriggerSource::SCC: source_str = "SCC"; break;
2816 case TriggerSource::CheatTemp: source_str = "Cheat (Temp)"; break;
2817 case TriggerSource::CheatPerm: source_str = "Cheat (Perm)"; break;
2818 }
2819 11888 Z_eventlog("Screen Secrets triggered by %s\n", source_str);
2820 }
2821 12340 }
2822
2823 // single:
2824 // >-1 : the singular triggering combo
2825 // -1: triggered by some other cause
2826 12132 void trigger_secrets_for_screen(TriggerSource source, mapscr* scr, bool high16only, int32_t single)
2827 {
2828 12132 log_trigger_secret_reason(source);
2829
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11680 times.
12132 if (single < 0)
2830 11680 get_screen_state(scr->screen).triggered_secrets = true;
2831
2832 12132 bool do_replay_comment = true;
2833 12132 bool from_active_screen = true;
2834 12132 trigger_secrets_for_screen_internal(create_screen_handles(scr), from_active_screen, high16only, single, do_replay_comment);
2835
2836 // Respect secret state carryovers for active screens.
2837
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11680 times.
12132 if (single >= 0) return;
2838
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 11655 times.
11680 if(scr->nocarry&mSECRET) return;
2839 11655 int cmap = scr->map;
2840 11655 int cscr = scr->screen;
2841 11655 int nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
2842 11655 int nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
2843
2844 11655 std::vector<int32_t> done;
2845
2/2
✓ Branch 0 taken 11450 times.
✓ Branch 1 taken 205 times.
11655 bool looped = (nmap==cmap+1 && nscr==cscr);
2846
2847
6/6
✓ Branch 0 taken 586 times.
✓ Branch 1 taken 11569 times.
✓ Branch 2 taken 86 times.
✓ Branch 3 taken 500 times.
✓ Branch 4 taken 500 times.
✓ Branch 5 taken 11655 times.
12155 while((nmap!=0) && !looped && !(nscr>=128))
2848 {
2849
7/8
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 93 times.
✓ Branch 3 taken 295 times.
✓ Branch 4 taken 93 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 89 times.
500 if (nmap - 1 == cur_map && is_in_current_region(nscr) && !get_screen_state(nscr).triggered_secrets)
2850 {
2851
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
2852
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 trigger_secrets_for_screen_internal(create_screen_handles(get_scr(nscr)), from_active_screen, high16only, single, do_replay_comment);
2853
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 get_screen_state(nscr).triggered_secrets = true;
2854 4 }
2855
2856 500 cmap=nmap;
2857 500 cscr=nscr;
2858 500 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
2859 500 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
2860
2861
2/2
✓ Branch 0 taken 443 times.
✓ Branch 1 taken 500 times.
943 for(auto it = done.begin(); it != done.end(); it++)
2862 {
2863
2/2
✓ Branch 0 taken 357 times.
✓ Branch 1 taken 86 times.
443 if(*it == ((nmap-1)<<7)+nscr)
2864 86 looped = true;
2865 443 }
2866
2867
1/2
✓ Branch 0 taken 500 times.
✗ Branch 1 not taken.
500 done.push_back(((nmap-1)<<7)+nscr);
2868 }
2869 12132 }
2870
2871 2550 void trigger_secrets_for_screen(TriggerSource source, int32_t screen, bool high16only, int32_t single)
2872 {
2873 2550 trigger_secrets_for_screen(source, get_scr(screen), high16only, single);
2874 2550 }
2875
2876 19223 void trigger_secrets_for_screen_internal(const screen_handles_t& screen_handles, bool from_active_screen, bool high16only, int32_t single, bool do_replay_comment)
2877 {
2878 19223 mapscr* scr = screen_handles[0].scr;
2879 19223 int screen = scr->screen;
2880
2881 // TODO(replays): No real reason for "do_replay_comment" to exist - I just did not want to update many replays when fixing
2882 // slopes in sideview mode (which required loading nearby screens in loadscr).
2883 // TODO(replays): This should just use `screen`.
2884
3/4
✓ Branch 0 taken 19223 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 18684 times.
19223 if (replay_is_active() && do_replay_comment)
2885
4/6
✓ Branch 0 taken 12136 times.
✓ Branch 1 taken 6548 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12136 times.
✓ Branch 4 taken 18684 times.
✗ Branch 5 not taken.
18684 replay_step_comment(fmt::format("trigger secrets scr={}", from_active_screen && scr != special_warp_return_scr ? screen : cur_screen));
2886
2887
2/2
✓ Branch 0 taken 7087 times.
✓ Branch 1 taken 12136 times.
19223 if (from_active_screen)
2888 {
2889 6099822 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
2890
2/4
✓ Branch 0 taken 6085024 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2662 times.
✗ Branch 3 not taken.
6407603 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
2891 319917 return trig.trigger_flags.get(TRIGFLAG_SECRETSTR);
2892 }, ctrigSECRETS);
2893 6087686 });
2894 12136 }
2895
2896 19223 int32_t ft=0; //Flag trigger?
2897 19223 int32_t msflag=0; // Misc. secret flag
2898
2899
2/2
✓ Branch 0 taken 3383248 times.
✓ Branch 1 taken 19223 times.
3402471 for(int32_t i=0; i<176; i++) //Do the 'trigger flags' (non 16-31)
2900 {
2901
4/4
✓ Branch 0 taken 79552 times.
✓ Branch 1 taken 3303696 times.
✓ Branch 2 taken 452 times.
✓ Branch 3 taken 79100 times.
3383248 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2902
2903 // Remember the misc. secret flag; if triggered, use this instead
2904
4/4
✓ Branch 0 taken 153551 times.
✓ Branch 1 taken 3150597 times.
✓ Branch 2 taken 87558 times.
✓ Branch 3 taken 65993 times.
3304148 if(scr->sflag[i]>=mfSECRETS01 && scr->sflag[i]<=mfSECRETS16)
2905 65993 msflag=sSECRET01+(scr->sflag[i]-mfSECRETS01);
2906
4/4
✓ Branch 0 taken 47862 times.
✓ Branch 1 taken 3190293 times.
✓ Branch 2 taken 47336 times.
✓ Branch 3 taken 526 times.
3238155 else if(combobuf[scr->data[i]].flag>=mfSECRETS01 && combobuf[scr->data[i]].flag<=mfSECRETS16)
2907 526 msflag=sSECRET01+(combobuf[scr->data[i]].flag-mfSECRETS01);
2908 else
2909 3237629 msflag=0;
2910
2911
4/4
✓ Branch 0 taken 922853 times.
✓ Branch 1 taken 2381295 times.
✓ Branch 2 taken 85 times.
✓ Branch 3 taken 922768 times.
3304148 if(!high16only || single>=0)
2912 {
2913 2381380 int32_t newflag = -1;
2914
2915
2/2
✓ Branch 0 taken 4762760 times.
✓ Branch 1 taken 2381380 times.
7144140 for(int32_t iter=0; iter<2; ++iter)
2916 {
2917 4762760 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2918
2919
2/2
✓ Branch 0 taken 2381380 times.
✓ Branch 1 taken 2381380 times.
4762760 if(iter==1) checkflag=scr->sflag[i]; //Placed
2920
2921 4762760 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2922
2/2
✓ Branch 0 taken 4750287 times.
✓ Branch 1 taken 12473 times.
4762760 if (ft != -1) //Change the combos for the secret
2923 {
2924 // Use misc. secret flag instead if one is present
2925
2/2
✓ Branch 0 taken 12441 times.
✓ Branch 1 taken 32 times.
12473 if(msflag!=0)
2926 32 ft=msflag;
2927
2928 12473 rpos_handle_t rpos_handle;
2929
2/2
✓ Branch 0 taken 6541 times.
✓ Branch 1 taken 5932 times.
12473 if (from_active_screen)
2930 {
2931 5932 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2932 5932 screen_combo_modify_preroutine(rpos_handle);
2933 5932 }
2934
2935
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12473 times.
12473 if(ft==sSECNEXT)
2936 {
2937 scr->data[i]++;
2938 }
2939 else
2940 {
2941 12473 scr->data[i] = scr->secretcombo[ft];
2942 12473 scr->cset[i] = scr->secretcset[ft];
2943 }
2944 12473 newflag = scr->secretflag[ft];
2945
2946
2/2
✓ Branch 0 taken 6541 times.
✓ Branch 1 taken 5932 times.
12473 if (from_active_screen)
2947 5932 screen_combo_modify_postroutine(rpos_handle);
2948 12473 }
2949 4762760 }
2950
2951
2/2
✓ Branch 0 taken 2368913 times.
✓ Branch 1 taken 12467 times.
2381380 if(newflag >-1) scr->sflag[i] = newflag; //Tiered secret
2952
2953
2/2
✓ Branch 0 taken 14288280 times.
✓ Branch 1 taken 2381380 times.
16669660 for(int32_t j=1; j<=6; j++) //Layers
2954 {
2955 14288280 mapscr* layer_scr = screen_handles[j].scr;
2956
2/2
✓ Branch 0 taken 4300978 times.
✓ Branch 1 taken 9987302 times.
14288280 if (!layer_scr) continue;
2957
2958
3/4
✓ Branch 0 taken 770 times.
✓ Branch 1 taken 4300208 times.
✓ Branch 2 taken 770 times.
✗ Branch 3 not taken.
4300978 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2959
2960 4300978 int32_t newflag2 = -1;
2961
2962 // Remember the misc. secret flag; if triggered, use this instead
2963
4/4
✓ Branch 0 taken 18068 times.
✓ Branch 1 taken 4282910 times.
✓ Branch 2 taken 6284 times.
✓ Branch 3 taken 11784 times.
4300978 if(layer_scr->sflag[i]>=mfSECRETS01 && layer_scr->sflag[i]<=mfSECRETS16)
2964 11784 msflag=sSECRET01+(layer_scr->sflag[i]-mfSECRETS01);
2965
4/4
✓ Branch 0 taken 132026 times.
✓ Branch 1 taken 4157168 times.
✓ Branch 2 taken 130774 times.
✓ Branch 3 taken 1252 times.
4289194 else if(combobuf[layer_scr->data[i]].flag>=mfSECRETS01 && combobuf[layer_scr->data[i]].flag<=mfSECRETS16)
2966 1252 msflag=sSECRET01+(combobuf[layer_scr->data[i]].flag-mfSECRETS01);
2967 else
2968 4287942 msflag=0;
2969
2970
2/2
✓ Branch 0 taken 8601956 times.
✓ Branch 1 taken 4300978 times.
12902934 for(int32_t iter=0; iter<2; ++iter)
2971 {
2972 8601956 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2973
2/2
✓ Branch 0 taken 4300978 times.
✓ Branch 1 taken 4300978 times.
8601956 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2974
2975 8601956 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2976
2/2
✓ Branch 0 taken 8600177 times.
✓ Branch 1 taken 1779 times.
8601956 if (ft != -1) //Change the combos for the secret
2977 {
2978 // Use misc. secret flag instead if one is present
2979
2/2
✓ Branch 0 taken 1777 times.
✓ Branch 1 taken 2 times.
1779 if(msflag!=0)
2980 2 ft=msflag;
2981
2982
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1779 times.
1779 if(ft==sSECNEXT)
2983 {
2984 layer_scr->data[i]++;
2985 }
2986 else
2987 {
2988 1779 layer_scr->data[i] = layer_scr->secretcombo[ft];
2989 1779 layer_scr->cset[i] = layer_scr->secretcset[ft];
2990 }
2991 1779 newflag2 = layer_scr->secretflag[ft];
2992 1779 int32_t c=layer_scr->data[i];
2993 1779 int32_t cs=layer_scr->cset[i];
2994
2995
3/4
✓ Branch 0 taken 908 times.
✓ Branch 1 taken 871 times.
✓ Branch 2 taken 908 times.
✗ Branch 3 not taken.
1779 if (from_active_screen && combobuf[c].type==cSPINTILE1) //Surely this means we can have spin tiles on layers 3+? Isn't that bad? ~Joe123
2996 {
2997 auto [offx, offy] = translate_screen_coordinates_to_world(screen, COMBOX(i), COMBOY(i));
2998 addenemy(screen,offx,offy,(cs<<12)+eSPINTILE1,combobuf[c].o_tile+zc_max(1,combobuf[c].frames));
2999 }
3000 1779 }
3001 8601956 }
3002
3003
2/2
✓ Branch 0 taken 1766 times.
✓ Branch 1 taken 4299212 times.
4300978 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered secret
3004 4300978 }
3005 2381380 }
3006 3304148 }
3007
3008 19223 word c = scr->numFFC();
3009
2/2
✓ Branch 0 taken 508334 times.
✓ Branch 1 taken 19223 times.
527557 for(word i=0; i<c; i++) //FFC 'trigger flags'
3010 {
3011
3/4
✓ Branch 0 taken 494280 times.
✓ Branch 1 taken 14054 times.
✓ Branch 2 taken 14054 times.
✗ Branch 3 not taken.
508334 if(single>=0) if(i+176!=single) continue;
3012
3013
3/4
✓ Branch 0 taken 166649 times.
✓ Branch 1 taken 327631 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 166649 times.
494280 if((!high16only)||(single>=0))
3014 {
3015 //for (int32_t iter=0; iter<1; ++iter) // Only one kind of FFC flag now.
3016 {
3017 327631 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3018 //No placed flags yet
3019
3020 327631 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
3021
2/2
✓ Branch 0 taken 327600 times.
✓ Branch 1 taken 31 times.
327631 if (ft != -1) //Change the ffc's combo
3022 {
3023
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(ft==sSECNEXT)
3024 {
3025 zc_ffc_modify(scr->ffcs[i], 1);
3026 }
3027 else
3028 {
3029 31 zc_ffc_set(scr->ffcs[i], scr->secretcombo[ft]);
3030 31 scr->ffcs[i].cset = scr->secretcset[ft];
3031 }
3032 31 }
3033 }
3034 327631 }
3035 494280 }
3036
3037
2/2
✓ Branch 0 taken 16725 times.
✓ Branch 1 taken 2498 times.
19223 if(checktrigger) //Hit all triggers->16-31
3038 {
3039 2498 checktrigger=false;
3040
3041
2/2
✓ Branch 0 taken 2474 times.
✓ Branch 1 taken 24 times.
2498 if(scr->flags6&fTRIGGERF1631)
3042 {
3043 24 int32_t tr = findtrigger(screen); //Normal flags
3044
3045
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 10 times.
24 if(tr)
3046 {
3047 14 Z_eventlog("Hit All Triggers->16-31 not fulfilled (%d trigger flag%s remain).\n", tr, tr>1?"s":"");
3048 14 goto endhe;
3049 }
3050 10 }
3051 2484 }
3052
3053
2/2
✓ Branch 0 taken 3380784 times.
✓ Branch 1 taken 19209 times.
3399993 for(int32_t i=0; i<176; i++) // Do the 16-31 secrets
3054 {
3055 //If it's an enemies->secret screen, only do the high 16 if told to
3056 //That way you can have secret and burn/bomb entrance separately
3057 3380784 bool old_enem_secret = get_qr(qr_ENEMIES_SECRET_ONLY_16_31);
3058
6/6
✓ Branch 0 taken 2780624 times.
✓ Branch 1 taken 600160 times.
✓ Branch 2 taken 85184 times.
✓ Branch 3 taken 3295600 times.
✓ Branch 4 taken 19536 times.
✓ Branch 5 taken 65648 times.
3380784 if(((!(old_enem_secret && (scr->flags2&fCLEARSECRET)) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM))
3059 {
3060 3315136 int32_t newflag = -1;
3061
3062
2/2
✓ Branch 0 taken 6630272 times.
✓ Branch 1 taken 3315136 times.
9945408 for(int32_t iter=0; iter<2; ++iter)
3063 {
3064 6630272 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
3065
3066
2/2
✓ Branch 0 taken 3315136 times.
✓ Branch 1 taken 3315136 times.
6630272 if(iter==1) checkflag=scr->sflag[i]; //Placed
3067
3068
4/4
✓ Branch 0 taken 200805 times.
✓ Branch 1 taken 6429467 times.
✓ Branch 2 taken 133230 times.
✓ Branch 3 taken 67575 times.
6630272 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3069 {
3070 67575 rpos_handle_t rpos_handle;
3071
2/2
✓ Branch 0 taken 10367 times.
✓ Branch 1 taken 57208 times.
67575 if (from_active_screen)
3072 {
3073 57208 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
3074 57208 screen_combo_modify_preroutine(rpos_handle);
3075 57208 }
3076
3077 67575 scr->data[i] = scr->secretcombo[checkflag-16+4];
3078 67575 scr->cset[i] = scr->secretcset[checkflag-16+4];
3079 67575 newflag = scr->secretflag[checkflag-16+4];
3080
3081
2/2
✓ Branch 0 taken 10367 times.
✓ Branch 1 taken 57208 times.
67575 if (from_active_screen)
3082 57208 screen_combo_modify_postroutine(rpos_handle);
3083 67575 }
3084 6630272 }
3085
3086
2/2
✓ Branch 0 taken 3247589 times.
✓ Branch 1 taken 67547 times.
3315136 if(newflag >-1) scr->sflag[i] = newflag; //Tiered flag
3087
3088
2/2
✓ Branch 0 taken 19890816 times.
✓ Branch 1 taken 3315136 times.
23205952 for(int32_t j=1; j<=6; j++) //Layers
3089 {
3090 19890816 mapscr* layer_scr = screen_handles[j].scr;
3091
2/2
✓ Branch 0 taken 5992096 times.
✓ Branch 1 taken 13898720 times.
19890816 if (!layer_scr) continue;
3092
3093 5992096 int32_t newflag2 = -1;
3094
3095
2/2
✓ Branch 0 taken 11984192 times.
✓ Branch 1 taken 5992096 times.
17976288 for(int32_t iter=0; iter<2; ++iter)
3096 {
3097 11984192 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
3098
3099
2/2
✓ Branch 0 taken 5992096 times.
✓ Branch 1 taken 5992096 times.
11984192 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
3100
3101
4/4
✓ Branch 0 taken 159433 times.
✓ Branch 1 taken 11824759 times.
✓ Branch 2 taken 136546 times.
✓ Branch 3 taken 22887 times.
11984192 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3102 {
3103 22887 layer_scr->data[i] = layer_scr->secretcombo[checkflag-16+4];
3104 22887 layer_scr->cset[i] = layer_scr->secretcset[checkflag-16+4];
3105 22887 newflag2 = layer_scr->secretflag[checkflag-16+4];
3106 22887 }
3107 11984192 }
3108
3109
2/2
✓ Branch 0 taken 5969209 times.
✓ Branch 1 taken 22887 times.
5992096 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered flag
3110 5992096 }
3111 3315136 }
3112 3380784 }
3113
3114
2/2
✓ Branch 0 taken 508074 times.
✓ Branch 1 taken 19209 times.
527283 for(word i=0; i<c; i++) // FFCs
3115 {
3116
6/6
✓ Branch 0 taken 468053 times.
✓ Branch 1 taken 40021 times.
✓ Branch 2 taken 15497 times.
✓ Branch 3 taken 492577 times.
✓ Branch 4 taken 3657 times.
✓ Branch 5 taken 11840 times.
508074 if((!(scr->flags2&fCLEARSECRET) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM)
3117 {
3118 496234 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3119
3120 //No placed flags yet
3121
4/4
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 496141 times.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 12 times.
496234 if((checkflag > 15)&&(checkflag < 32)) //If we find a flag, change the combo
3122 {
3123
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (from_active_screen)
3124 9 zc_ffc_set(scr->ffcs[i], scr->secretcombo[checkflag - 16 + 4]);
3125 else
3126 3 scr->ffcs[i].data = scr->secretcombo[checkflag - 16 + 4];
3127 12 scr->ffcs[i].cset = scr->secretcset[checkflag-16+4];
3128 12 }
3129 496234 }
3130 527283 }
3131
3132 endhe:
3133
3134
1/2
✓ Branch 0 taken 19223 times.
✗ Branch 1 not taken.
19223 if (scr->flags4&fDISABLETIME) //Finish timed warp if 'Secrets Disable Timed Warp'
3135 {
3136 if (from_active_screen)
3137 activated_timed_warp = true;
3138 scr->timedwarptics = 0;
3139 }
3140 19223 }
3141
3142 // x,y are world coordinates.
3143 // Returns true if there is a flag (either combo, screen, or ffc) at (x, y).
3144 // Out parameters will be set if the flag is Trigger->Self, which modifies how secrets will be triggered.
3145 13982906 static bool has_flag_trigger(int32_t x, int32_t y, int32_t flag, rpos_t& out_rpos, bool& out_single16)
3146 {
3147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13982906 times.
13982906 if (!is_in_world_bounds(x, y)) return false;
3148
3149 13982906 bool found_cflag = false;
3150 13982906 bool found_nflag = false;
3151 13982906 bool single16 = false;
3152 13982906 rpos_t rpos = rpos_t::None;
3153
3154
2/2
✓ Branch 0 taken 13980804 times.
✓ Branch 1 taken 97868060 times.
111848864 for (int32_t layer = -1; layer < 6; layer++)
3155 {
3156
2/2
✓ Branch 0 taken 97865958 times.
✓ Branch 1 taken 2102 times.
97868060 if (MAPFLAG2(layer, x, y) == flag)
3157 {
3158 2102 found_nflag = true;
3159 2102 break;
3160 }
3161 97865958 }
3162
3163
2/2
✓ Branch 0 taken 13982517 times.
✓ Branch 1 taken 97878647 times.
111861164 for (int32_t layer = -1; layer < 6; layer++)
3164 {
3165
2/2
✓ Branch 0 taken 97878258 times.
✓ Branch 1 taken 389 times.
97878647 if (MAPCOMBOFLAG2(layer, x, y) == flag)
3166 {
3167 389 found_cflag = true;
3168 389 break;
3169 }
3170 97878258 }
3171
3172
2/2
✓ Branch 0 taken 97880342 times.
✓ Branch 1 taken 13982906 times.
111863248 for (int32_t i=-1; i<6; i++) // Look for Trigger->Self on all layers
3173 {
3174
2/2
✓ Branch 0 taken 97865628 times.
✓ Branch 1 taken 14714 times.
97880342 if (found_nflag) // Trigger->Self (a.k.a Singular) is inherent
3175 {
3176
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14602 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
14714 if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE) && (MAPFLAG2(i, x, y) == flag))
3177 {
3178 112 rpos = COMBOPOS_REGION(x, y);
3179 112 }
3180
3/4
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 14546 times.
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
14602 else if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE16) && (MAPFLAG2(i, x, y) == flag))
3181 {
3182 56 rpos = COMBOPOS_REGION(x, y);
3183 56 single16 = true;
3184 56 }
3185 14714 }
3186
3187
2/2
✓ Branch 0 taken 97877619 times.
✓ Branch 1 taken 2723 times.
97880342 if (found_cflag) // Trigger->Self (a.k.a Singular) is non-inherent
3188 {
3189
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 2468 times.
✓ Branch 2 taken 255 times.
✗ Branch 3 not taken.
2723 if ((MAPFLAG2(i, x, y) == mfSINGLE) && (MAPCOMBOFLAG2(i, x, y) == flag))
3190 {
3191 255 rpos = COMBOPOS_REGION(x, y);
3192 255 }
3193
3/4
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 2439 times.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
2468 else if ((MAPFLAG2(i, x, y) == mfSINGLE16) && (MAPCOMBOFLAG2(i, x, y) == flag))
3194 {
3195 29 rpos = COMBOPOS_REGION(x, y);
3196 29 single16 = true;
3197 29 }
3198 2723 }
3199 97880342 }
3200
3201 13982906 out_rpos = rpos;
3202 13982906 out_single16 = single16;
3203
4/4
✓ Branch 0 taken 13980804 times.
✓ Branch 1 taken 2102 times.
✓ Branch 2 taken 13980419 times.
✓ Branch 3 taken 385 times.
13982906 return found_nflag || found_cflag || MAPFFCOMBOFLAG(x,y) == flag;
3204 13982906 }
3205
3206 4604586 bool trigger_secrets_if_flag(int32_t x, int32_t y, int32_t flag, bool setflag)
3207 {
3208
8/8
✓ Branch 0 taken 4604346 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 4602449 times.
✓ Branch 3 taken 1897 times.
✓ Branch 4 taken 4601929 times.
✓ Branch 5 taken 520 times.
✓ Branch 6 taken 952 times.
✓ Branch 7 taken 4600977 times.
4604586 if (x < -16 || y < -16 || x >= world_w || y >= world_h) return false;
3209
3210 4600977 mapscr* scr = NULL;
3211 4600977 int32_t screen = -1;
3212 4600977 rpos_t trigger_rpos = rpos_t::None;
3213 4600977 bool single16 = false;
3214
3215 4600977 std::vector<std::pair<int, int>> coords;
3216
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x, y});
3217
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x + 15, y});
3218
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x, y + 15});
3219
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x + 15, y + 15});
3220 4600977 std::vector<rpos_t> rposes_seen;
3221
2/2
✓ Branch 0 taken 4598479 times.
✓ Branch 1 taken 18398387 times.
87336590 for (auto [x, y] : coords)
3222 {
3223
2/4
✓ Branch 0 taken 18398387 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18398387 times.
✗ Branch 3 not taken.
36796774 rpos_t rpos = COMBOPOS_REGION_B(x, y);
3224
2/2
✓ Branch 0 taken 18184458 times.
✓ Branch 1 taken 213929 times.
18398387 if (rpos == rpos_t::None)
3225 213929 continue;
3226
3227
4/6
✓ Branch 0 taken 18184458 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18184458 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 18184447 times.
36368916 if (MAPFFCOMBOFLAG(x, y) == flag)
3228 {
3229
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 screen = get_screen_for_world_xy(x, y);
3230 11 break;
3231 }
3232
3233 18184447 bool seen = false;
3234
2/2
✓ Branch 0 taken 13982906 times.
✓ Branch 1 taken 22894140 times.
36877046 for (rpos_t r : rposes_seen)
3235 {
3236
2/2
✓ Branch 0 taken 18692599 times.
✓ Branch 1 taken 4201541 times.
22894140 if (r == rpos)
3237 {
3238 4201541 seen = true;
3239 4201541 break;
3240 }
3241 }
3242
2/2
✓ Branch 0 taken 13982906 times.
✓ Branch 1 taken 4201541 times.
18184447 if (seen)
3243 4201541 continue;
3244
3245
1/2
✓ Branch 0 taken 13982906 times.
✗ Branch 1 not taken.
13982906 rposes_seen.push_back(rpos);
3246
4/6
✓ Branch 0 taken 13982906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13982906 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2487 times.
✓ Branch 5 taken 13980419 times.
27965812 if (has_flag_trigger(x, y, flag, trigger_rpos, single16))
3247 {
3248
2/4
✓ Branch 0 taken 2487 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2487 times.
✗ Branch 3 not taken.
4974 screen = get_screen_for_world_xy(x, y);
3249 2487 break;
3250 }
3251 }
3252
3253
3/4
✓ Branch 0 taken 2498 times.
✓ Branch 1 taken 4598479 times.
✓ Branch 2 taken 2498 times.
✗ Branch 3 not taken.
4600977 if (screen != -1) scr = get_scr(screen);
3254
2/2
✓ Branch 0 taken 2498 times.
✓ Branch 1 taken 4598479 times.
4600977 if (!scr) return false;
3255
3256
2/2
✓ Branch 0 taken 2046 times.
✓ Branch 1 taken 452 times.
2498 if (trigger_rpos == rpos_t::None)
3257 {
3258 2046 checktrigger = true;
3259
1/2
✓ Branch 0 taken 2046 times.
✗ Branch 1 not taken.
2046 trigger_secrets_for_screen(TriggerSource::Unspecified, screen);
3260 2046 }
3261 else
3262 {
3263 452 checktrigger = true;
3264
2/4
✓ Branch 0 taken 452 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 452 times.
✗ Branch 3 not taken.
452 trigger_secrets_for_screen(TriggerSource::Singular, scr, single16, RPOS_TO_POS(trigger_rpos));
3265 }
3266
3267
1/2
✓ Branch 0 taken 2498 times.
✗ Branch 1 not taken.
2498 sfx(scr->secretsfx);
3268
3269
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 2477 times.
2498 if(scr->flags6&fTRIGGERFPERM)
3270 {
3271
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 int32_t flags_remaining = findtrigger(screen); //Normal flags
3272
3273
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 9 times.
21 if (flags_remaining)
3274 {
3275
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 Z_eventlog("Hit All Triggers->Perm Secret not fulfilled (%d trigger flag%s remain).\n", flags_remaining, flags_remaining>1?"s":"");
3276 12 setflag=false;
3277 12 }
3278
3279 // Only actually trigger secrets now if 1) all triggers are gone and 2) QR qr_ALLTRIG_PERMSEC_NO_TEMP is off, in
3280 // which case only the screen state for mSECRET may be set below.
3281
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 3 times.
21 if (!flags_remaining && !get_qr(qr_ALLTRIG_PERMSEC_NO_TEMP))
3282 {
3283
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 trigger_secrets_for_screen(TriggerSource::Unspecified, scr, scr->flags6&fTRIGGERF1631, -1);
3284 6 }
3285 21 }
3286
3287
5/6
✓ Branch 0 taken 2384 times.
✓ Branch 1 taken 114 times.
✓ Branch 2 taken 2384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1108 times.
✓ Branch 5 taken 1276 times.
2498 if (setflag && canPermSecret(cur_dmap, screen))
3288
2/2
✓ Branch 0 taken 813 times.
✓ Branch 1 taken 463 times.
2089 if(!(scr->flags5&fTEMPSECRETS))
3289
1/2
✓ Branch 0 taken 813 times.
✗ Branch 1 not taken.
813 setmapflag(scr, mSECRET);
3290
3291 2498 return true;
3292 4604586 }
3293
3294 15389700 void update_slopes()
3295 {
3296
2/2
✓ Branch 0 taken 142356 times.
✓ Branch 1 taken 15389700 times.
15532056 for (auto& p : slopes)
3297 {
3298 142356 slope_object& s = p.second;
3299 142356 s.updateslope(); //sets old x/y poses
3300 }
3301 15389700 }
3302
3303 14930055 void update_freeform_combos()
3304 {
3305 14930055 ffscript_engine(false);
3306
2/2
✓ Branch 0 taken 24172 times.
✓ Branch 1 taken 14905883 times.
14930055 if ( !FFCore.system_suspend[susptUPDATEFFC] )
3307 {
3308 14905883 int wrap_right = world_w + 32;
3309 14905883 int wrap_bottom = world_h + 32;
3310
3311 488487575 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
3312 473581692 mapscr* scr = ffc_handle.scr;
3313 473581692 ffcdata& thisffc = *ffc_handle.ffc;
3314
3315 // Combo 0?
3316
2/2
✓ Branch 0 taken 47283515 times.
✓ Branch 1 taken 426298177 times.
473581692 if(thisffc.data==0)
3317 426298177 return;
3318
3319 // Changer?
3320
2/2
✓ Branch 0 taken 562821 times.
✓ Branch 1 taken 46720694 times.
47283515 if(thisffc.flags&ffc_changer)
3321 562821 return;
3322
3323 // Stationary?
3324
2/2
✓ Branch 0 taken 9844 times.
✓ Branch 1 taken 46710850 times.
46720694 if(thisffc.flags&ffc_stationary)
3325 9844 return;
3326
3327 // Frozen because Hero's holding up an item?
3328
3/4
✓ Branch 0 taken 157429 times.
✓ Branch 1 taken 46553421 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 157429 times.
46710850 if(Hero.getHoldClk()>0 && (thisffc.flags&ffc_ignoreholdup)==0)
3329 157429 return;
3330
3331 // Check for changers
3332
2/2
✓ Branch 0 taken 31045342 times.
✓ Branch 1 taken 15508079 times.
46553421 if (thisffc.link==0)
3333 {
3334 446641935 for_some_ffcs([&](const ffc_handle_t& other_ffc_handle) {
3335
2/2
✓ Branch 0 taken 15506442 times.
✓ Branch 1 taken 415627414 times.
431133856 if (ffc_handle.id == other_ffc_handle.id)
3336 15506442 return true;
3337
3338 415627414 ffcdata& otherffc = *other_ffc_handle.ffc;
3339 // Combo 0?
3340
2/2
✓ Branch 0 taken 147056060 times.
✓ Branch 1 taken 268571354 times.
415627414 if(otherffc.data==0)
3341 268571354 return true;
3342
3343 // Not a changer?
3344
2/2
✓ Branch 0 taken 142874031 times.
✓ Branch 1 taken 4182029 times.
147056060 if(!(otherffc.flags&ffc_changer))
3345 142874031 return true;
3346
3347 // Ignore this changer?
3348
4/4
✓ Branch 0 taken 564215 times.
✓ Branch 1 taken 3617814 times.
✓ Branch 2 taken 308097 times.
✓ Branch 3 taken 3309717 times.
4182029 if((otherffc.x.getInt()==thisffc.changer_x&&otherffc.y.getInt()==thisffc.changer_y) || thisffc.flags&ffc_ignorechanger)
3349 872312 return true;
3350
3351
3/4
✓ Branch 0 taken 2870799 times.
✓ Branch 1 taken 438918 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3663 times.
3313380 if((isonline(thisffc.x.getZLong(), thisffc.y.getZLong(), thisffc.prev_changer_x, thisffc.prev_changer_y, otherffc.x.getZLong(), otherffc.y.getZLong()) || // Along the line, or...
3352 ( // At exactly the same position,
3353
2/2
✓ Branch 0 taken 217547 times.
✓ Branch 1 taken 2653252 times.
2870799 (thisffc.x==otherffc.x && thisffc.y==otherffc.y))
3354
2/2
✓ Branch 0 taken 2435705 times.
✓ Branch 1 taken 2653252 times.
217547 ||
3355 //or imprecision and close enough
3356
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5306504 ( (thisffc.flags&ffc_imprecisionchanger) && ((abs(thisffc.x.getZLong() - otherffc.x.getZLong()) < 10000) && abs(thisffc.y.getZLong() - otherffc.y.getZLong()) < 10000) )
3357 )
3358 && //and...
3359
2/2
✓ Branch 0 taken 3663 times.
✓ Branch 1 taken 2870960 times.
2874623 (thisffc.prev_changer_x>-10000000 && thisffc.prev_changer_y>-10000000)) // This isn't the first frame on this screen
3360 {
3361 3663 zc_ffc_changer(thisffc, otherffc, ffc_handle.id, other_ffc_handle.id);
3362 3663 return false;
3363 }
3364
3365 2870960 return true;
3366 430082568 });
3367 15508079 }
3368
3369
2/2
✓ Branch 0 taken 31045342 times.
✓ Branch 1 taken 15508079 times.
46553421 ffcdata* linked_ffc = thisffc.link ? get_ffc_handle(thisffc.link - 1).ffc : nullptr;
3370
4/4
✓ Branch 0 taken 15508079 times.
✓ Branch 1 taken 31045342 times.
✓ Branch 2 taken 15430786 times.
✓ Branch 3 taken 15614556 times.
46553421 if (linked_ffc ? !linked_ffc->delay : !thisffc.delay)
3371 {
3372
4/4
✓ Branch 0 taken 182609 times.
✓ Branch 1 taken 15431947 times.
✓ Branch 2 taken 85331 times.
✓ Branch 3 taken 97278 times.
15614556 if(thisffc.link && (thisffc.link-1) != ffc_handle.id)
3373 {
3374 97278 thisffc.prev_changer_x = thisffc.x.getZLong();
3375 97278 thisffc.prev_changer_y = thisffc.y.getZLong();
3376 97278 thisffc.x += linked_ffc->vx;
3377 97278 thisffc.y += linked_ffc->vy;
3378 97278 }
3379 else
3380 {
3381 15517278 thisffc.prev_changer_x = thisffc.x.getZLong();
3382 15517278 thisffc.prev_changer_y = thisffc.y.getZLong();
3383 15517278 thisffc.x += thisffc.vx;
3384 15517278 thisffc.y += thisffc.vy;
3385 15517278 thisffc.vx += thisffc.ax;
3386 15517278 thisffc.vy += thisffc.ay;
3387
3388
3389
2/2
✓ Branch 0 taken 1192093 times.
✓ Branch 1 taken 14325185 times.
15517278 if(get_qr(qr_OLD_FFC_SPEED_CAP))
3390 {
3391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vx>128) thisffc.vx=128;
3392
3393
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vx<-128) thisffc.vx=-128;
3394
3395
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vy>128) thisffc.vy=128;
3396
3397
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vy<-128) thisffc.vy=-128;
3398 14325185 }
3399 }
3400 15614556 }
3401 else
3402 {
3403
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 76132 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1161 times.
30938865 if(!thisffc.link || (thisffc.link-1) == ffc_handle.id)
3404 76132 thisffc.delay--;
3405 }
3406
3407 // Check if the FFC's off the side of the screen
3408
3409 // Left
3410
2/2
✓ Branch 0 taken 10449 times.
✓ Branch 1 taken 15681400 times.
15691849 if(thisffc.x<-32)
3411 {
3412
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 10196 times.
10449 if(scr->flags6&fWRAPAROUNDFF)
3413 {
3414 253 thisffc.x = wrap_right+(thisffc.x+32);
3415 253 thisffc.solid_update(false);
3416 253 thisffc.prev_changer_y = thisffc.y.getZLong();
3417 // Re-enable previous changer
3418 253 thisffc.changer_x = -1000;
3419 253 thisffc.changer_y = -1000;
3420 253 }
3421
2/2
✓ Branch 0 taken 10127 times.
✓ Branch 1 taken 69 times.
10196 else if(thisffc.x<-64)
3422 {
3423 69 zc_ffc_set(thisffc, 0);
3424 69 thisffc.flags&=~ffc_carryover;
3425 69 }
3426 10449 }
3427 // Right
3428
2/2
✓ Branch 0 taken 15681219 times.
✓ Branch 1 taken 181 times.
15681400 else if(thisffc.x>=wrap_right)
3429 {
3430
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 53 times.
181 if(scr->flags6&fWRAPAROUNDFF)
3431 {
3432 128 thisffc.x = thisffc.x-wrap_right-32;
3433 128 thisffc.solid_update(false);
3434 128 thisffc.prev_changer_y = thisffc.y.getZLong();
3435 128 thisffc.changer_x = -1000;
3436 128 thisffc.changer_y = -1000;
3437 128 }
3438 else
3439 {
3440 53 zc_ffc_set(thisffc, 0);
3441 53 thisffc.flags&=~ffc_carryover;
3442 }
3443 181 }
3444
3445 // Top
3446
2/2
✓ Branch 0 taken 25806 times.
✓ Branch 1 taken 15666043 times.
15691849 if(thisffc.y<-32)
3447 {
3448
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25798 times.
25806 if(scr->flags6&fWRAPAROUNDFF)
3449 {
3450 8 thisffc.y = wrap_bottom+(thisffc.y+32);
3451 8 thisffc.solid_update(false);
3452 8 thisffc.prev_changer_x = thisffc.x.getZLong();
3453 8 thisffc.changer_x = -1000;
3454 8 thisffc.changer_y = -1000;
3455 8 }
3456
2/2
✓ Branch 0 taken 25481 times.
✓ Branch 1 taken 317 times.
25798 else if(thisffc.y<-64)
3457 {
3458 317 zc_ffc_set(thisffc, 0);
3459 317 thisffc.flags&=~ffc_carryover;
3460 317 }
3461 25806 }
3462 // Bottom
3463
2/2
✓ Branch 0 taken 15665175 times.
✓ Branch 1 taken 868 times.
15666043 else if(thisffc.y>=wrap_bottom)
3464 {
3465
2/2
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 115 times.
868 if(scr->flags6&fWRAPAROUNDFF)
3466 {
3467 753 thisffc.y = thisffc.y-wrap_bottom-32;
3468 753 thisffc.solid_update(false);
3469 753 thisffc.prev_changer_y = thisffc.x.getZLong();
3470 753 thisffc.changer_x = -1000;
3471 753 thisffc.changer_y = -1000;
3472 753 }
3473 else
3474 {
3475 115 zc_ffc_set(thisffc, 0);
3476 115 thisffc.flags&=~ffc_carryover;
3477 }
3478 868 }
3479 15691849 thisffc.solid_update();
3480 442720120 });
3481 14905883 }
3482 14930055 }
3483
3484 bool hitflag(int32_t x, int32_t y, int32_t flagtype, byte layers)
3485 {
3486 for(int q = 0; q < 7; ++q)
3487 {
3488 if(layers&(1<<q)) //if layer is to be checked
3489 if(MAPFLAG2(q-1,x,y)==flagtype||MAPCOMBOFLAG2(q-1,x,y)==flagtype) //matching flag
3490 return true;
3491 }
3492 return false;
3493 }
3494
3495 231 optional<int> nextscr(int screen, int dir)
3496 {
3497 231 auto [m, s] = nextscr2(cur_map, screen, dir);
3498
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231 times.
231 if (m == -1) return nullopt;
3499 462 return (m<<7) + s;
3500 231 }
3501
3502 1064 std::pair<int32_t, int32_t> nextscr2(int32_t dir)
3503 {
3504 1064 int32_t map = cur_map;
3505
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1064 times.
1064 int32_t screen = screenscrolling ? scrolling_hero_screen : Hero.current_screen;
3506 1064 return nextscr2(map, screen, dir);
3507 }
3508
3509 5582 std::pair<int32_t, int32_t> nextscr2(int map, int screen, int32_t dir)
3510 {
3511 5582 screen = screen_index_direction(screen, (direction)dir);
3512
3513 // need to check for screens on other maps, 's' not valid, etc.
3514 5582 int32_t index = (hero_scr->sidewarpindex >> (dir*2))&3;
3515
3516 // Fun fact: when a scrolling warp is triggered, this function
3517 // is never even called! - Saf
3518
2/2
✓ Branch 0 taken 3330 times.
✓ Branch 1 taken 2252 times.
6126 if(hero_scr->sidewarptype[index] == 3) // scrolling warp
3519 {
3520
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 527 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 697 times.
2252 switch(dir)
3521 {
3522 case up:
3523
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 399 times.
482 if(!(hero_scr->flags2&wfUP)) goto nowarp;
3524
3525 83 break;
3526
3527 case down:
3528
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 448 times.
527 if(!(hero_scr->flags2&wfDOWN)) goto nowarp;
3529
3530 79 break;
3531
3532 case left:
3533
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 337 times.
546 if(!(hero_scr->flags2&wfLEFT)) goto nowarp;
3534
3535 209 break;
3536
3537 case right:
3538
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 524 times.
697 if(!(hero_scr->flags2&wfRIGHT)) goto nowarp;
3539
3540 173 break;
3541 }
3542
3543 544 map = DMaps[hero_scr->sidewarpdmap[index]].map;
3544 544 screen = hero_scr->sidewarpscr[index] + DMaps[hero_scr->sidewarpdmap[index]].xoff;
3545 544 }
3546
3547 nowarp:
3548
4/4
✓ Branch 0 taken 5518 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 5406 times.
5582 if(screen<0||screen>=128)
3549 176 return {-1, -1};
3550
3551 5406 return {map, screen};
3552 5582 }
3553
3554 403 optional<int> nextscr_mi(int mi, int dir)
3555 {
3556 403 int map = mi/MAPSCRSNORMAL;
3557 403 int screen = mi%MAPSCRSNORMAL;
3558 403 auto [m, s] = nextscr2(map, screen, dir);
3559
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 402 times.
403 if (m == -1) return nullopt;
3560 804 return (m<<7) + s;
3561 403 }
3562
3563 2297 void bombdoor(int32_t x,int32_t y)
3564 {
3565
2/2
✓ Branch 0 taken 2276 times.
✓ Branch 1 taken 21 times.
2297 if (!is_in_world_bounds(x, y))
3566 21 return;
3567
3568 2276 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
3569 2276 mapscr* scr = rpos_handle.scr;
3570 2276 int screen = scr->screen;
3571 3084 auto [x0, y0] = translate_screen_coordinates_to_world(rpos_handle.screen);
3572 #define CHECK_RECT(x,y,rx1,ry1,rx2,ry2) (isinRect(x,y,x0+rx1,y0+ry1,x0+rx2,y0+ry2))
3573
3574
12/12
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 2197 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 69 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 69 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 69 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 69 times.
2276 if(scr->door[0]==dBOMB && CHECK_RECT(x,y,100,0,139,48))
3575 {
3576 69 scr->door[0]=dBOMBED;
3577 69 putdoor(scr, scrollbuf, 0, dBOMBED);
3578 69 setmapflag(scr, mDOOR_UP);
3579 69 markBmap(-1, screen);
3580
3581
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 if(auto v = nextscr(screen, up))
3582 {
3583 69 setmapflag_mi(*v, mDOOR_DOWN);
3584 69 markBmap(-1,*v-(get_currdmap()<<7));
3585 69 }
3586 69 }
3587
3588
12/12
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2227 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 39 times.
2276 if(scr->door[1]==dBOMB && CHECK_RECT(x,y,100,112,139,176))
3589 {
3590 39 scr->door[1]=dBOMBED;
3591 39 putdoor(scr, scrollbuf, 1, dBOMBED);
3592 39 setmapflag(scr, mDOOR_DOWN);
3593 39 markBmap(-1, rpos_handle.screen);
3594
3595
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if(auto v = nextscr(rpos_handle.screen, down))
3596 {
3597 39 setmapflag_mi(*v, mDOOR_UP);
3598 39 markBmap(-1,*v-(get_currdmap()<<7));
3599 39 }
3600 39 }
3601
3602
12/12
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 2209 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 51 times.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 51 times.
2276 if(scr->door[2]==dBOMB && CHECK_RECT(x,y,0,60,48,98))
3603 {
3604 51 scr->door[2]=dBOMBED;
3605 51 putdoor(scr, scrollbuf, 2, dBOMBED);
3606 51 setmapflag(scr, mDOOR_LEFT);
3607 51 markBmap(-1, rpos_handle.screen);
3608
3609
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto v = nextscr(rpos_handle.screen, left))
3610 {
3611 51 setmapflag_mi(*v, mDOOR_RIGHT);
3612 51 markBmap(-1,*v-(get_currdmap()<<7));
3613 51 }
3614 51 }
3615
3616
12/12
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2190 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 72 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 72 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 72 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 72 times.
2276 if(scr->door[3]==dBOMB && CHECK_RECT(x,y,192,60,240,98))
3617 {
3618 72 scr->door[3]=dBOMBED;
3619 72 putdoor(scr, scrollbuf, 3, dBOMBED);
3620 72 setmapflag(scr, mDOOR_RIGHT);
3621 72 markBmap(-1, rpos_handle.screen);
3622
3623
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if(auto v = nextscr(rpos_handle.screen, right))
3624 {
3625 72 setmapflag_mi(*v, mDOOR_LEFT);
3626 72 markBmap(-1,*v-(get_currdmap()<<7));
3627 72 }
3628 72 }
3629 2297 }
3630
3631 7119637297 void draw_cmb(BITMAP* dest, int32_t x, int32_t y, int32_t cid, int32_t cset,
3632 bool over, bool transp)
3633 {
3634 7119637297 auto& cmb = combobuf[cid];
3635
2/2
✓ Branch 0 taken 93673 times.
✓ Branch 1 taken 7119543624 times.
7119637297 if(cmb.animflags & AF_EDITOR_ONLY)
3636 93673 return;
3637
2/2
✓ Branch 0 taken 3924435462 times.
✓ Branch 1 taken 3195108162 times.
7119543624 if(over)
3638 {
3639
2/2
✓ Branch 0 taken 841117 times.
✓ Branch 1 taken 3923594345 times.
3924435462 if(cmb.animflags & AF_TRANSPARENT)
3640 841117 transp = !transp;
3641
2/2
✓ Branch 0 taken 328615081 times.
✓ Branch 1 taken 3595820381 times.
3924435462 if(transp)
3642 328615081 overcombotranslucent(dest, x, y, cid, cset, 128);
3643 3595820381 else overcombo(dest, x, y, cid, cset);
3644 3924435462 }
3645 3195108162 else putcombo(dest, x, y, cid, cset);
3646 7119637297 }
3647 7119645745 void draw_cmb_pos(BITMAP* dest, int32_t x, int32_t y, rpos_t rpos, int32_t cid,
3648 int32_t cset, byte layer, bool over, bool transp)
3649 {
3650
2/2
✓ Branch 0 taken 847534117 times.
✓ Branch 1 taken 6272111628 times.
7119645745 if (rpos != rpos_t::None)
3651 {
3652 6272111628 rpos_t plrpos = COMBOPOS_REGION_B(Hero.x+8, Hero.y+8);
3653
2/2
✓ Branch 0 taken 749524 times.
✓ Branch 1 taken 6271362104 times.
6272111628 if (plrpos != rpos_t::None)
3654 {
3655 6271362104 bool dosw = false;
3656
4/4
✓ Branch 0 taken 67998 times.
✓ Branch 1 taken 6271294106 times.
✓ Branch 2 taken 59550 times.
✓ Branch 3 taken 8448 times.
6271362104 if (rpos == hooked_comborpos && (hooked_layerbits & (1<<layer)))
3657 {
3658
1/2
✓ Branch 0 taken 8448 times.
✗ Branch 1 not taken.
8448 if(hooked_undercombos[layer] > -1)
3659 {
3660 draw_cmb(dest, x, y,
3661 hooked_undercombos[layer], hooked_undercombos[layer+7], over, transp);
3662 }
3663 8448 dosw = true;
3664 8448 }
3665
4/4
✓ Branch 0 taken 35599524 times.
✓ Branch 1 taken 6235754132 times.
✓ Branch 2 taken 8448 times.
✓ Branch 3 taken 35591076 times.
6271353656 else if (rpos == plrpos && (hooked_layerbits & (1<<(layer+8))))
3666 {
3667 8448 dosw = true;
3668 8448 }
3669
2/2
✓ Branch 0 taken 6271345208 times.
✓ Branch 1 taken 16896 times.
6271362104 if (dosw)
3670 {
3671
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 16896 times.
✗ Branch 3 not taken.
16896 switch (Hero.switchhookstyle)
3672 {
3673 default: case swPOOF:
3674 break; //Nothing special here
3675 case swFLICKER:
3676 {
3677
2/2
✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 8448 times.
16896 if(abs(Hero.switchhookclk-33)&0b1000)
3678 8448 break; //Drawn this frame
3679 8448 return; //Not drawn this frame
3680 }
3681 case swRISE:
3682 {
3683 //Draw rising up
3684 y -= 8-(abs(Hero.switchhookclk-32)/4);
3685 break;
3686 }
3687 }
3688 8448 }
3689 6271353656 }
3690 6272103180 }
3691
3692 7119637297 draw_cmb(dest, x, y, cid, cset, over, transp);
3693 7119645745 }
3694
3695 // `draw_cmb_pos` only does meaningful work if the combo being drawn is within the bounds of
3696 // the `bmp` bitmap. However, even getting to the point where `puttile16` (for example) knows
3697 // to cull is somewhat expensive. Since it can only draw 16x16 pixels, we can do the equivalent
3698 // culling here by determining the rows/columns that are within the bitmap bounds. This nets
3699 // on the order of ~30 FPS in uncapped mode on my machine, depending on the viewport/region size.
3700 //
3701 // These two inequalities must be true for `draw_cmb_pos` to do anything useful:
3702 //
3703 // -16 < comboPositionX*16 + x < bitmapWidth
3704 // -16 < comboPositionY*16 + y < bitmapHeight
3705 //
3706 // The following start/end values are derived directly from the above.
3707 //
3708 // `x` and `y` are the offsets the combos will be drawn into the bitmap.
3709 44033859 static void get_bounds_for_draw_cmb_calls(BITMAP* bmp, int x, int y, int& start_x, int& end_x, int& start_y, int& end_y)
3710 {
3711 // if (bmp->clip)
3712 // {
3713 // start_x = MAX(0, ceil((bmp->cl - 15 - x) / 16.0));
3714 // end_x = MIN(16, ceil((bmp->cr - x) / 16.0));
3715 // start_y = MAX(0, ceil((bmp->ct - 15 - y) / 16.0));
3716 // end_y = MIN(11, ceil((bmp->cb - y) / 16.0));
3717 // return;
3718 // }
3719
3720
2/2
✓ Branch 0 taken 2404962 times.
✓ Branch 1 taken 41628897 times.
44033859 start_x = MAX(0, ceil((-15 - x) / 16.0));
3721
2/2
✓ Branch 0 taken 2412938 times.
✓ Branch 1 taken 41620921 times.
44033859 end_x = MIN(16, ceil((bmp->w - x) / 16.0));
3722
2/2
✓ Branch 0 taken 42495310 times.
✓ Branch 1 taken 1538549 times.
44033859 start_y = MAX(0, ceil((-15 - y) / 16.0));
3723
2/2
✓ Branch 0 taken 1874535 times.
✓ Branch 1 taken 42159324 times.
44033859 end_y = MIN(11, ceil((bmp->h - y) / 16.0));
3724 44033859 }
3725
3726 195715508 void do_ffc_layer(BITMAP* bmp, int32_t layer, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3727 {
3728
1/2
✓ Branch 0 taken 195715508 times.
✗ Branch 1 not taken.
195715508 if(!show_ffcs) return;
3729 195715508 mapscr* scr = screen_handle.scr;
3730 195715508 mapscr* base_scr = screen_handle.base_scr;
3731
3732 195715508 y += playing_field_offset;
3733
3734 195715508 bool is_overhead = layer == -1000;
3735
2/2
✓ Branch 0 taken 53248376 times.
✓ Branch 1 taken 142467132 times.
195715508 bool is_bg_layer = layer < 0 && !is_overhead;
3736
2/2
✓ Branch 0 taken 35534254 times.
✓ Branch 1 taken 160181254 times.
195715508 int real_layer = is_bg_layer ? abs(layer) : layer;
3737
2/2
✓ Branch 0 taken 195715508 times.
✓ Branch 1 taken 5610067558 times.
5805783066 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3738 {
3739
2/2
✓ Branch 0 taken 217455144 times.
✓ Branch 1 taken 5392612414 times.
5610067558 if (base_scr->ffcs[i].data == 0)
3740 5392612414 continue;
3741
3/4
✓ Branch 0 taken 39536116 times.
✓ Branch 1 taken 177919028 times.
✓ Branch 2 taken 39536116 times.
✗ Branch 3 not taken.
217455144 if (is_bg_layer && base_scr->ffcs[i].layer == layer)
3742 ; // ffc is set negative, skip bg layer flag checks
3743 else
3744 {
3745
4/4
✓ Branch 0 taken 39536089 times.
✓ Branch 1 taken 177919055 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 19768031 times.
217455144 if(real_layer == 2 && (is_bg_layer != XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG)))
3746 19768031 continue;
3747
4/4
✓ Branch 0 taken 39535883 times.
✓ Branch 1 taken 158151230 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 19767825 times.
197687113 else if (real_layer == 3 && (is_bg_layer != XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)))
3748 19767825 continue;
3749
4/4
✓ Branch 0 taken 158156192 times.
✓ Branch 1 taken 19763096 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 138388134 times.
177919288 if (real_layer > -1 && base_scr->ffcs[i].layer != real_layer)
3750 138388134 continue;
3751 }
3752
3753
6/6
✓ Branch 0 taken 3311080 times.
✓ Branch 1 taken 36220074 times.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 3305970 times.
✓ Branch 4 taken 2626 times.
✓ Branch 5 taken 2484 times.
39531154 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3754 2484 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3755
3756 39528670 base_scr->ffcs[i].draw_ffc(bmp, x, y, is_overhead);
3757 39528670 }
3758 195715508 }
3759 177523976 void _do_current_ffc_layer(BITMAP* bmp, int32_t layer)
3760 {
3761
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 177523976 times.
177523976 if(!show_ffcs) return;
3762 359972894 for_every_base_screen_in_region([&](mapscr* base_scr, unsigned int region_scr_x, unsigned int region_scr_y) {
3763 182448918 screen_handle_t handle = {base_scr, base_scr, base_scr->screen, 0};
3764 182448918 do_ffc_layer(bmp, layer, handle, 0, 0);
3765 182448918 });
3766 177523976 }
3767 110575276 void do_scrolling_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3768 {
3769 110575276 mapscr* scr = screen_handle.scr;
3770 110575276 mapscr* base_scr = screen_handle.base_scr;
3771
3772
4/4
✓ Branch 0 taken 69331638 times.
✓ Branch 1 taken 41243638 times.
✓ Branch 2 taken 41243638 times.
✓ Branch 3 taken 110575276 times.
110575276 if (type == -3 || type == -4)
3773 {
3774 82487276 y += playing_field_offset;
3775
3776
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
82487276 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3777 {
3778 if (base_scr->ffcs[i].data == 0)
3779 continue;
3780
3781 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3782 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3783
3784 base_scr->ffcs[i].draw_ffc(bmp, x, y, (type==-4));
3785 }
3786 return;
3787 }
3788
3789 110575276 x -= viewport.x;
3790 110575276 y -= viewport.y - playing_field_offset;
3791
3792 110575276 bool over = true, transp = false;
3793 110575276 int layer = screen_handle.layer;
3794
3795
7/8
✓ Branch 0 taken 86308690 times.
✓ Branch 1 taken 24266586 times.
✓ Branch 2 taken 15025887 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 62989195 times.
✓ Branch 5 taken 23319495 times.
✓ Branch 6 taken 3907230 times.
✓ Branch 7 taken 5333469 times.
110575276 switch(type ? type : layer)
3796 {
3797 case -2: //push blocks
3798
2/2
✓ Branch 0 taken 21745557 times.
✓ Branch 1 taken 41243638 times.
62989195 if (scr)
3799 {
3800
2/2
✓ Branch 0 taken 3827218032 times.
✓ Branch 1 taken 62327171 times.
3863263051 for(int32_t i=0; i<176; i++)
3801 {
3802 3827218032 int32_t mf=scr->sflag[i], mf2 = combobuf[scr->data[i]].flag;
3803
3804
10/10
✓ Branch 0 taken 3827047688 times.
✓ Branch 1 taken 170344 times.
✓ Branch 2 taken 3825570483 times.
✓ Branch 3 taken 1477205 times.
✓ Branch 4 taken 3824937244 times.
✓ Branch 5 taken 633239 times.
✓ Branch 6 taken 53394531 times.
✓ Branch 7 taken 3771542713 times.
✓ Branch 8 taken 100280201 times.
✓ Branch 9 taken 57147412 times.
3870809545 if(mf==mfPUSHUD || mf==mfPUSH4 || mf==mfPUSHED || ((mf>=mfPUSHLR)&&(mf<=mfPUSHRINS))
3805
6/8
✓ Branch 0 taken 3822054595 times.
✓ Branch 1 taken 50511882 times.
✓ Branch 2 taken 3822054595 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3822054595 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 43591513 times.
✓ Branch 7 taken 3778463082 times.
3824937244 || mf2==mfPUSHUD || mf2==mfPUSH4 || mf2==mfPUSHED || ((mf2>=mfPUSHLR)&&(mf2<=mfPUSHRINS)))
3806 {
3807
4/4
✓ Branch 0 taken 5124570 times.
✓ Branch 1 taken 782430 times.
✓ Branch 2 taken 3849 times.
✓ Branch 3 taken 5120721 times.
206467402 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3808 5907000 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3809 5907000 }
3810 3841517494 }
3811 62327171 }
3812 103570809 return;
3813
3814 case -1: //over combo
3815
1/2
✓ Branch 0 taken 23319495 times.
✗ Branch 1 not taken.
23319495 if (scr)
3816 {
3817
2/2
✓ Branch 0 taken 4104231120 times.
✓ Branch 1 taken 23319495 times.
4127550615 for(int32_t i=0; i<176; i++)
3818 {
3819
2/2
✓ Branch 0 taken 4084901200 times.
✓ Branch 1 taken 19329920 times.
4104231120 if(combo_class_buf[combobuf[scr->data[i]].type].overhead)
3820 {
3821
4/4
✓ Branch 0 taken 15574819 times.
✓ Branch 1 taken 3755101 times.
✓ Branch 2 taken 22336 times.
✓ Branch 3 taken 15552483 times.
19329920 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3822 19329920 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3823 19329920 }
3824 4104231120 }
3825 23319495 }
3826 23319495 return;
3827
3828 case 1:
3829 case 4:
3830 case 5:
3831 case 6:
3832
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15025887 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15025887 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3833 {
3834
1/2
✓ Branch 0 taken 15025887 times.
✗ Branch 1 not taken.
15025887 if (scr)
3835 {
3836
2/2
✓ Branch 0 taken 13331185 times.
✓ Branch 1 taken 1694702 times.
15025887 if(base_scr->layeropacity[layer-1]!=255)
3837 1694702 transp = true;
3838 15025887 break;
3839 }
3840 }
3841 return;
3842
3843 case 2:
3844
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3907230 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3907230 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3845 {
3846
1/2
✓ Branch 0 taken 3907230 times.
✗ Branch 1 not taken.
3907230 if (scr)
3847 {
3848
2/2
✓ Branch 0 taken 3670944 times.
✓ Branch 1 taken 236286 times.
3907230 if(base_scr->layeropacity[layer-1]!=255)
3849 236286 transp = true;
3850
3851
2/2
✓ Branch 0 taken 3759775 times.
✓ Branch 1 taken 147455 times.
3907230 if(XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3852 147455 over = false;
3853
3854 3907230 break;
3855 }
3856 }
3857 return;
3858
3859 case 3:
3860
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5333469 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5333469 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3861 {
3862
1/2
✓ Branch 0 taken 5333469 times.
✗ Branch 1 not taken.
5333469 if (scr)
3863 {
3864
2/2
✓ Branch 0 taken 5258193 times.
✓ Branch 1 taken 75276 times.
5333469 if(base_scr->layeropacity[layer-1]!=255)
3865 75276 transp = true;
3866
3867
2/2
✓ Branch 0 taken 36654 times.
✓ Branch 1 taken 237618 times.
5333469 if(XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
3868
2/2
✓ Branch 0 taken 274272 times.
✓ Branch 1 taken 5059197 times.
5333469 && !XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3869 237618 over = false;
3870
3871 5333469 break;
3872 }
3873 }
3874 return;
3875 }
3876
3877 int start_x, end_x, start_y, end_y;
3878 24266586 get_bounds_for_draw_cmb_calls(bmp, x, y, start_x, end_x, start_y, end_y);
3879
2/2
✓ Branch 0 taken 24266586 times.
✓ Branch 1 taken 257467292 times.
281733878 for (int cy = start_y; cy < end_y; cy++)
3880 {
3881
2/2
✓ Branch 0 taken 3897791767 times.
✓ Branch 1 taken 257467292 times.
4155259059 for (int cx = start_x; cx < end_x; cx++)
3882 {
3883 3897791767 int i = cx + cy*16;
3884
4/4
✓ Branch 0 taken 3440940732 times.
✓ Branch 1 taken 456851035 times.
✓ Branch 2 taken 11831072 times.
✓ Branch 3 taken 3429109660 times.
3897791767 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3885 3897791767 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, over, transp);
3886 3897791767 }
3887 257467292 }
3888 69331638 }
3889
3890 279529705 bool lenscheck(mapscr* scr, int layer)
3891 {
3892
4/4
✓ Branch 0 taken 279353133 times.
✓ Branch 1 taken 176572 times.
✓ Branch 2 taken 176572 times.
✓ Branch 3 taken 279529705 times.
279529705 if(layer < 0 || layer > 6) return true;
3893
2/2
✓ Branch 0 taken 259692525 times.
✓ Branch 1 taken 19837180 times.
279529705 if(get_qr(qr_OLD_LENS_LAYEREFFECT))
3894 {
3895
2/2
✓ Branch 0 taken 209793109 times.
✓ Branch 1 taken 49899416 times.
259692525 if(!layer) return true;
3896
8/8
✓ Branch 0 taken 34936541 times.
✓ Branch 1 taken 174856568 times.
✓ Branch 2 taken 258970 times.
✓ Branch 3 taken 34677571 times.
✓ Branch 4 taken 146134 times.
✓ Branch 5 taken 259680 times.
✓ Branch 6 taken 326536 times.
✓ Branch 7 taken 34497169 times.
209793109 if((layer==(int32_t)(scr->lens_layer&7)+1) && ((scr->lens_layer&llLENSSHOWS && !lensclk) || (scr->lens_layer&llLENSHIDES && lensclk)))
3897 586216 return false;
3898 209353737 }
3899 else
3900 {
3901
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19837180 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 19837180 times.
19837180 if((lensclk ? scr->lens_hide : scr->lens_show) & (1<<layer))
3902 return false;
3903 }
3904 229190917 return true;
3905 279353133 }
3906
3907 165164297 void do_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3908 {
3909 165164297 bool showlayer = true;
3910 165164297 mapscr* base_scr = screen_handle.base_scr;
3911 165164297 int layer = screen_handle.layer;
3912
2/2
✓ Branch 0 taken 46584941 times.
✓ Branch 1 taken 118579356 times.
165164297 int target = type ? type : layer;
3913
3/4
✓ Branch 0 taken 118579356 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22483787 times.
✓ Branch 3 taken 24101154 times.
165164297 switch(target)
3914 {
3915 case -2:
3916
1/2
✓ Branch 0 taken 22483787 times.
✗ Branch 1 not taken.
22483787 if(!show_layer_push)
3917 showlayer = false;
3918 22483787 break;
3919
3920 case -1:
3921
1/2
✓ Branch 0 taken 24101154 times.
✗ Branch 1 not taken.
24101154 if(!show_layer_over)
3922 showlayer = false;
3923 24101154 break;
3924
3925 case 1: case 2: case 3:
3926 case 4: case 5: case 6:
3927 118579356 showlayer = show_layers[target];
3928 118579356 break;
3929 }
3930
3931
2/2
✓ Branch 0 taken 46584941 times.
✓ Branch 1 taken 118579356 times.
165164297 if(!type)
3932 {
3933
2/2
✓ Branch 0 taken 118443158 times.
✓ Branch 1 taken 136198 times.
118579356 if(!lenscheck(base_scr,layer))
3934 136198 showlayer = false;
3935 118579356 }
3936
3937
2/2
✓ Branch 0 taken 136198 times.
✓ Branch 1 taken 165028099 times.
165164297 if(showlayer)
3938 {
3939
6/6
✓ Branch 0 taken 69423586 times.
✓ Branch 1 taken 95604513 times.
✓ Branch 2 taken 24358534 times.
✓ Branch 3 taken 45065052 times.
✓ Branch 4 taken 91948 times.
✓ Branch 5 taken 24266586 times.
165028099 if (screen_handle.scr && (type || !(base_scr->hidelayers & (1 << (layer)))))
3940 {
3941 69331638 do_scrolling_layer(bmp, type, screen_handle, x, y);
3942
4/4
✓ Branch 0 taken 24266586 times.
✓ Branch 1 taken 45065052 times.
✓ Branch 2 taken 22269756 times.
✓ Branch 3 taken 1996830 times.
69331638 if(!type && !get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
3943
2/2
✓ Branch 0 taken 1996254 times.
✓ Branch 1 taken 576 times.
1997406 if(mblock2.draw(bmp,layer))
3944 576 do_primitives(bmp, SPLAYER_MOVINGBLOCK);
3945 69331638 }
3946 165028099 }
3947 165164297 }
3948
3949 107033734 void do_layer_primitives(BITMAP *bmp, int32_t layer)
3950 {
3951 107033734 bool showlayer = true;
3952
3953
2/4
✓ Branch 0 taken 107033734 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 107033734 times.
107033734 if(layer >= 0 && layer <= 6)
3954 {
3955 107033734 showlayer = show_layers[layer];
3956
3957
2/2
✓ Branch 0 taken 106907132 times.
✓ Branch 1 taken 126602 times.
107033734 if(!lenscheck(origin_scr,layer))
3958 126602 showlayer = false;
3959 107033734 }
3960
3961
2/2
✓ Branch 0 taken 126602 times.
✓ Branch 1 taken 106907132 times.
107033734 if (showlayer)
3962 106907132 do_primitives(bmp, layer);
3963 107033734 }
3964
3965 // Called by do_walkflags
3966 void put_walkflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
3967 {
3968 newcombo const &c = combobuf[cmbdat];
3969
3970 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3971
3972 int32_t xx = x-xofs;
3973 int32_t yy = y+playing_field_offset-yofs;
3974
3975 int32_t bridgedetected = 0;
3976
3977 for(int32_t i=0; i<4; i++)
3978 {
3979 int32_t tx=((i&2)<<2)+xx - viewport.x;
3980 int32_t ty=((i&1)<<3)+yy - viewport.y;
3981 int32_t tx2=((i&2)<<2)+x - viewport.x;
3982 int32_t ty2=((i&1)<<3)+y - viewport.y;
3983 for (int32_t j = lyr-1; j <= 1; j++)
3984 {
3985 if (get_qr(qr_OLD_BRIDGE_COMBOS))
3986 {
3987 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && !_walkflag_layer(tx2,ty2,j))
3988 {
3989 bridgedetected |= (1<<i);
3990 }
3991 }
3992 else
3993 {
3994 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && _effectflag_layer(tx2,ty2,j))
3995 {
3996 bridgedetected |= (1<<i);
3997 }
3998 }
3999 }
4000 if ((bridgedetected & (1<<i)))
4001 {
4002 if (i >= 3) break;
4003 else continue;
4004 }
4005 bool doladdercheck = true;
4006
4007 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4008 {
4009 for(int32_t k=0; k<8; k+=2)
4010 for(int32_t j=0; j<8; j+=2)
4011 if(((k+j)/2)%2)
4012 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,makecol(85,85,255));
4013 }
4014 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4015 {
4016 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4017 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4018 rectfill(dest,tx,ty,tx+7,ty+7,makecol(85,85,255));
4019 else rectfill(dest,tx,ty,tx+7,ty+7,makecol(170,170,170));
4020 }
4021
4022 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4023 {
4024 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4025 {
4026 for(int32_t k=0; k<8; k+=2)
4027 for(int32_t j=0; j<8; j+=2)
4028 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,((k+j)/2)%2 ? makecol(165,105,8) : makecol(170,170,170));
4029 }
4030 else
4031 {
4032 int32_t color = makecol(178,36,36);
4033
4034 if(isstepable(cmbdat)&& (!doladdercheck))
4035 color=makecol(165,105,8);
4036 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4037 color=makecol(170,170,170);
4038
4039 rectfill(dest,tx,ty,tx+7,ty+7,color);
4040 }
4041 }
4042 }
4043
4044 // Draw damage combos
4045 bool dmg = combo_class_buf[combobuf[MAPCOMBO2(-1,xx,yy)].type].modify_hp_amount
4046 || combo_class_buf[combobuf[MAPCOMBO2(0,xx,yy)].type].modify_hp_amount
4047 || combo_class_buf[combobuf[MAPCOMBO2(1,xx,yy)].type].modify_hp_amount;
4048
4049 if(dmg)
4050 {
4051 int32_t color = makecol(255,255,0);
4052 if (bridgedetected <= 0)
4053 {
4054 for(int32_t k=0; k<16; k+=2)
4055 for(int32_t j=0; j<16; j+=2)
4056 if(((k+j)/2)%2)
4057 {
4058 int32_t x0 = x - viewport.x;
4059 int32_t y0 = y - viewport.y;
4060 rectfill(dest,x0+k,y0+j,x0+k+1,y0+j+1,color);
4061 }
4062 }
4063 else
4064 {
4065 for(int32_t i=0; i<4; i++)
4066 {
4067 if (!(bridgedetected & (1<<i)))
4068 {
4069 int32_t tx=((i&2)<<2)+x - viewport.x;
4070 int32_t ty=((i&1)<<3)+y - viewport.y;
4071 for(int32_t k=0; k<8; k+=2)
4072 for(int32_t j=0; j<8; j+=2)
4073 if((k+j)%4 < 2) rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,color);
4074 }
4075 }
4076 }
4077 }
4078 }
4079 static void put_walkflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4080 {
4081 ALLEGRO_COLOR col_solid = al_map_rgba(178,36,36,info_opacity);
4082 ALLEGRO_COLOR col_water1 = al_map_rgba(85,85,255,info_opacity);
4083 ALLEGRO_COLOR col_lhook = al_map_rgba(170,170,170,info_opacity);
4084 ALLEGRO_COLOR col_stepable = al_map_rgba(165,105,8,info_opacity);
4085 ALLEGRO_COLOR col_dmg = al_map_rgba(255,255,0,info_opacity);
4086 newcombo const &c = combobuf[cmbdat];
4087
4088 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
4089
4090 int32_t xx = x-viewport.x;
4091 int32_t yy = y+playing_field_offset-viewport.y;
4092
4093 int32_t bridgedetected = 0;
4094
4095 // Draw damage combos
4096 bool dmg = combo_class_buf[c.type].modify_hp_amount;
4097
4098 for(int32_t i=0; i<4; i++)
4099 {
4100 int32_t tx=((i&2)<<2)+xx;
4101 int32_t ty=((i&1)<<3)+yy;
4102 int32_t tx2=((i&2)<<2)+x;
4103 int32_t ty2=((i&1)<<3)+y;
4104 for (int32_t m = lyr-1; m <= 1; m++)
4105 {
4106 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4107 {
4108 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && !_walkflag_layer(tx2, ty2, m))
4109 {
4110 bridgedetected |= (1<<i);
4111 }
4112 }
4113 else
4114 {
4115 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && _effectflag_layer(tx2, ty2, m))
4116 {
4117 bridgedetected |= (1<<i);
4118 }
4119 }
4120 }
4121 if ((bridgedetected & (1<<i)))
4122 continue;
4123 bool doladdercheck = true;
4124
4125 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4126 {
4127 for(int32_t k=0; k<8; k+=2)
4128 for(int32_t j=0; j<8; j+=2)
4129 if(((k+j)/2)%2)
4130 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_water1);
4131 }
4132 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4133 {
4134 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4135 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4136 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_water1);
4137 else al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_lhook);
4138 }
4139
4140 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4141 {
4142 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4143 {
4144 for(int32_t k=0; k<8; k+=2)
4145 for(int32_t j=0; j<8; j+=2)
4146 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,((k+j)/2)%2 ? col_stepable : col_lhook);
4147 }
4148 else
4149 {
4150 ALLEGRO_COLOR* color = &col_solid;
4151
4152 if(isstepable(cmbdat)&& (!doladdercheck))
4153 color=&col_stepable;
4154 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4155 color=&col_lhook;
4156
4157 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,*color);
4158 }
4159 }
4160
4161 if(dmg)
4162 {
4163 for(int32_t k=0; k<8; k+=2)
4164 for(int32_t j=0; j<8; j+=2)
4165 if((k+j)%4 < 2) al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_dmg);
4166 }
4167 }
4168 }
4169
4170 void put_effectflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
4171 {
4172 newcombo const &c = combobuf[cmbdat];
4173
4174 int32_t xx = x-xofs-viewport.x;
4175 int32_t yy = y+playing_field_offset-yofs-viewport.y;
4176
4177 for(int32_t i=0; i<4; i++)
4178 {
4179 int32_t tx=((i&2)<<2)+xx;
4180 int32_t ty=((i&1)<<3)+yy;
4181
4182 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4183 {
4184 int32_t color = vc(10);
4185
4186 rectfill(dest,tx,ty,tx+7,ty+7,color);
4187 }
4188 }
4189 }
4190 static void put_effectflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4191 {
4192 ALLEGRO_COLOR col_eff = al_map_rgba(85,255,85,info_opacity);
4193 newcombo const &c = combobuf[cmbdat];
4194
4195 int32_t xx = x-viewport.x;
4196 int32_t yy = y+playing_field_offset-viewport.y;
4197
4198 for(int32_t i=0; i<4; i++)
4199 {
4200 int32_t tx=((i&2)<<2)+xx;
4201 int32_t ty=((i&1)<<3)+yy;
4202
4203 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4204 {
4205 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_eff);
4206 }
4207 }
4208 }
4209
4210 void draw_ladder_platform(BITMAP* dest, int32_t x, int32_t y, int32_t c)
4211 {
4212 for(auto cx = 0; cx < 256; cx += 16)
4213 {
4214 for(auto cy = 0; cy < 176; cy += 16)
4215 {
4216 if(isSVLadder(cx,cy))
4217 {
4218 auto nx = cx+x, ny = cy+y;
4219 if(cy && !isSVLadder(cx,cy-16))
4220 line(dest,nx,ny,nx+15,ny,c);
4221 rectfill(dest,nx,ny,nx+3,ny+15,c);
4222 rectfill(dest,nx+12,ny,nx+15,ny+15,c);
4223 rectfill(dest,nx+4,ny+2,nx+11,ny+5,c);
4224 rectfill(dest,nx+4,ny+10,nx+11,ny+13,c);
4225 }
4226 else if(isSVPlatform(cx,cy))
4227 {
4228 line(dest,cx+x,cy+y,cx+x+15,cy+y,c);
4229 }
4230 }
4231 }
4232 }
4233 void draw_ladder_platform_a5(int32_t x, int32_t y, ALLEGRO_COLOR c)
4234 {
4235 for(auto cx = 0; cx < 256; cx += 16)
4236 {
4237 for(auto cy = 0; cy < 176; cy += 16)
4238 {
4239 if(isSVLadder(cx,cy))
4240 {
4241 auto nx = cx+x, ny = cy+y;
4242 if(cy && !isSVLadder(cx,cy-16))
4243 al_draw_line(nx,ny,nx+15,ny,c,1);
4244 al_draw_filled_rectangle(nx,ny,nx+4,ny+16,c);
4245 al_draw_filled_rectangle(nx+12,ny,nx+16,ny+16,c);
4246 al_draw_filled_rectangle(nx+4,ny+2,nx+12,ny+6,c);
4247 al_draw_filled_rectangle(nx+4,ny+10,nx+12,ny+14,c);
4248 }
4249 else if(isSVPlatform(cx,cy))
4250 {
4251 al_draw_line(cx+x,cy+y,cx+x+15,cy+y,c,1);
4252 }
4253 }
4254 }
4255 }
4256
4257 // Walkflags L4 cheat
4258 void do_walkflags(const screen_handles_t& screen_handles, int32_t x, int32_t y)
4259 {
4260 if (!show_walkflags)
4261 return;
4262
4263 start_info_bmp();
4264
4265 mapscr* scr = screen_handles[0].scr;
4266 for(int32_t i=0; i<176; i++)
4267 {
4268 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4269 }
4270
4271 for(int32_t k=0; k<2; k++)
4272 {
4273 scr = screen_handles[k + 1].scr;
4274
4275 if (scr)
4276 {
4277 for(int32_t i=0; i<176; i++)
4278 {
4279 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], k%2+1);
4280 }
4281 }
4282 }
4283
4284 end_info_bmp();
4285 }
4286
4287 void do_walkflags(int32_t x, int32_t y)
4288 {
4289 if (!show_walkflags)
4290 return;
4291
4292 x += -viewport.x;
4293 y += playing_field_offset - viewport.y;
4294
4295 start_info_bmp();
4296
4297 draw_ladder_platform_a5(x,y,al_map_rgba(165,105,8,info_opacity));
4298 draw_solid_objects_a5(x,y,al_map_rgba(178,36,36,info_opacity));
4299 draw_slopes_a5(x,y,al_map_rgba(255,85,255,info_opacity));
4300
4301 end_info_bmp();
4302 }
4303
4304 // Effectflags L4 cheat
4305 void do_effectflags(mapscr* scr, int32_t x, int32_t y)
4306 {
4307 if(show_effectflags)
4308 {
4309 start_info_bmp();
4310
4311 for(int32_t i=0; i<176; i++)
4312 {
4313 put_effectflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4314 }
4315
4316 end_info_bmp();
4317 }
4318 }
4319
4320 400489 void calc_darkroom_combos(mapscr* scr, int offx, int offy)
4321 {
4322 400489 int map = scr->map;
4323 400489 int screen = scr->screen;
4324
4325
2/2
✓ Branch 0 taken 2803423 times.
✓ Branch 1 taken 400489 times.
3203912 for(int32_t lyr = 0; lyr < 7; ++lyr)
4326 {
4327 2803423 mapscr* scr = get_scr_layer(map, screen, lyr);
4328
2/2
✓ Branch 0 taken 1829718 times.
✓ Branch 1 taken 973705 times.
2803423 if (!scr->is_valid()) continue;
4329
4330
2/2
✓ Branch 0 taken 322030368 times.
✓ Branch 1 taken 1829718 times.
323860086 for(int32_t q = 0; q < 176; ++q)
4331 {
4332 322030368 newcombo const& cmb = combobuf[scr->data[q]];
4333
2/2
✓ Branch 0 taken 320498295 times.
✓ Branch 1 taken 1532073 times.
322030368 if(cmb.type == cTORCH)
4334 {
4335 1532073 do_torch_combo(cmb, COMBOX(q)+8+offx, COMBOY(q)+8+offy, darkscr_bmp);
4336 1532073 }
4337 322030368 }
4338 1829718 }
4339 400489 }
4340
4341 400489 void calc_darkroom_ffcs(mapscr* scr, int offx, int offy)
4342 {
4343 400489 word c = scr->numFFC();
4344
2/2
✓ Branch 0 taken 704965 times.
✓ Branch 1 taken 400489 times.
1105454 for(int q = 0; q < c; ++q)
4345 {
4346 704965 newcombo const& cmb = combobuf[scr->ffcs[q].data];
4347
2/2
✓ Branch 0 taken 690157 times.
✓ Branch 1 taken 14808 times.
704965 if(cmb.type == cTORCH)
4348 {
4349 14808 int cx = scr->ffcs[q].x.getInt()+(scr->ffEffectWidth(q)/2)+offx;
4350 14808 int cy = (scr->ffcs[q].y.getInt())+(scr->ffEffectHeight(q)/2)+offy;
4351 14808 do_torch_combo(cmb, cx, cy, darkscr_bmp);
4352 14808 }
4353 704965 }
4354 400489 }
4355
4356 struct nearby_screen_t
4357 {
4358 int screen;
4359 int offx;
4360 int offy;
4361 screen_handles_t screen_handles;
4362 };
4363 typedef std::vector<nearby_screen_t> nearby_screens_t;
4364
4365 16081416 static nearby_screens_t get_nearby_screens_non_scrolling_region()
4366 {
4367 16081416 nearby_screens_t nearby_screens;
4368
4369 16081416 mapscr* base_scr = origin_scr;
4370
1/2
✓ Branch 0 taken 16081416 times.
✗ Branch 1 not taken.
16081416 auto& nearby_screen = nearby_screens.emplace_back();
4371 16081416 nearby_screen.screen = cur_screen;
4372
1/2
✓ Branch 0 taken 16081416 times.
✗ Branch 1 not taken.
16081416 nearby_screen.screen_handles = create_screen_handles(base_scr);
4373
4374 16081416 return nearby_screens;
4375
1/2
✓ Branch 0 taken 16081416 times.
✗ Branch 1 not taken.
16081416 }
4376
4377 48296 static nearby_screens_t get_nearby_screens_scrolling_region()
4378 {
4379 48296 nearby_screens_t nearby_screens;
4380
4381
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x0 = viewport.left() / 256;
4382
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x1 = (viewport.right() - 1) / 256;
4383
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y0 = viewport.top() / 176;
4384
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y1 = (viewport.bottom() - 1) / 176;
4385
4386
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x0 = std::clamp(screens_x0, 0, 15);
4387
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x1 = std::clamp(screens_x1, 0, 15);
4388
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y0 = std::clamp(screens_y0, 0, 8);
4389
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y1 = std::clamp(screens_y1, 0, 8);
4390
4391
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 79928 times.
128224 for (int x = screens_x0; x <= screens_x1; x++)
4392 {
4393
2/2
✓ Branch 0 taken 169672 times.
✓ Branch 1 taken 79928 times.
249600 for (int y = screens_y0; y <= screens_y1; y++)
4394 {
4395 169672 int screen = cur_screen + x + y*16;
4396
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!is_in_current_region(screen)) continue;
4397
4398
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 mapscr* base_scr = get_scr(screen);
4399
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!base_scr->is_valid()) continue;
4400
4401
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
4402
4403
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto& nearby_screen = nearby_screens.emplace_back();
4404 169672 nearby_screen.screen = screen;
4405 169672 nearby_screen.offx = offx;
4406 169672 nearby_screen.offy = offy;
4407
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 nearby_screen.screen_handles = create_screen_handles(base_scr);
4408 169672 }
4409 79928 }
4410
4411 48296 return nearby_screens;
4412
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 }
4413
4414 3658 static nearby_screens_t get_nearby_screens_smooth_maze()
4415 {
4416 3658 nearby_screens_t nearby_screens;
4417
4418
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x0 = viewport.left() / 256;
4419
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x1 = (viewport.right() - 1) / 256;
4420
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y0 = viewport.top() / 176;
4421
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y1 = (viewport.bottom() - 1) / 176;
4422
4423
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.left() < 0) screens_x0--;
4424
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.top() < 0) screens_y0--;
4425
4426
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 7308 times.
10966 for (int x = screens_x0; x <= screens_x1; x++)
4427 {
4428
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 7308 times.
25908 for (int y = screens_y0; y <= screens_y1; y++)
4429 {
4430 18600 int screen = -1;
4431 mapscr* base_scr;
4432 int offx, offy;
4433
4434 18600 mapscr* maze_scr = maze_state.scr;
4435 18600 int maze_screen = maze_scr->screen;
4436
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_x = get_region_relative_dx(maze_screen);
4437
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_y = get_region_relative_dy(maze_screen);
4438 18600 int maze_screen_dx = x - maze_screen_x;
4439 18600 int maze_screen_dy = y - maze_screen_y;
4440 18600 int exitdir = maze_scr->exitdir;
4441
4442 bool should_draw_maze_screen;
4443
2/2
✓ Branch 0 taken 9052 times.
✓ Branch 1 taken 9548 times.
18600 if (maze_state.lost)
4444 {
4445 9548 should_draw_maze_screen = true;
4446 9548 }
4447 else
4448 {
4449 9052 should_draw_maze_screen = true;
4450
4/6
✓ Branch 0 taken 9052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6844 times.
✓ Branch 3 taken 2208 times.
✓ Branch 4 taken 6844 times.
✗ Branch 5 not taken.
9052 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != exitdir && XY_DELTA_TO_DIR(0, maze_screen_dy) != exitdir;
4451
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 5202 times.
9052 if (maze_state.enter_dir != dir_invalid)
4452
4/6
✓ Branch 0 taken 3850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3304 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 3304 times.
✗ Branch 5 not taken.
3850 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != maze_state.enter_dir && XY_DELTA_TO_DIR(0, maze_screen_dy) != maze_state.enter_dir;
4453 }
4454
4455
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (should_draw_maze_screen)
4456 {
4457 16048 screen = maze_state.scr->screen;
4458 16048 base_scr = maze_state.scr;
4459
1/2
✓ Branch 0 taken 16048 times.
✗ Branch 1 not taken.
16048 std::tie(offx, offy) = translate_screen_coordinates_to_world(cur_screen + x + y*16);
4460 16048 }
4461
4462
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (screen == -1)
4463 {
4464 2552 screen = cur_screen + x + y*16;
4465
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!is_in_current_region(screen)) continue;
4466
4467
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 base_scr = get_scr(screen);
4468
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!base_scr->is_valid()) continue;
4469
4470
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 std::tie(offx, offy) = translate_screen_coordinates_to_world(screen);
4471 2552 }
4472
4473
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 auto& nearby_screen = nearby_screens.emplace_back();
4474 18600 nearby_screen.screen = screen;
4475 18600 nearby_screen.offx = offx;
4476 18600 nearby_screen.offy = offy;
4477
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 nearby_screen.screen_handles = create_screen_handles(base_scr);
4478 18600 }
4479 7308 }
4480
4481 3658 return nearby_screens;
4482
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 }
4483
4484 16133370 static nearby_screens_t get_nearby_screens()
4485 {
4486
4/4
✓ Branch 0 taken 9214 times.
✓ Branch 1 taken 16124156 times.
✓ Branch 2 taken 3658 times.
✓ Branch 3 taken 5556 times.
16133370 if (maze_state.active && maze_state.loopy)
4487 3658 return get_nearby_screens_smooth_maze();
4488
4489
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 16081416 times.
16129712 if (is_in_scrolling_region())
4490 48296 return get_nearby_screens_scrolling_region();
4491
4492 16081416 return get_nearby_screens_non_scrolling_region();
4493 16133370 }
4494
4495 209961559 static void for_every_nearby_screen(const nearby_screens_t& nearby_screens, const std::function <void (screen_handles_t, int, int, int)>& fn)
4496 {
4497
2/2
✓ Branch 0 taken 211746161 times.
✓ Branch 1 taken 209961559 times.
421707720 for (auto& nearby_screen : nearby_screens)
4498 211746161 fn(nearby_screen.screen_handles, nearby_screen.screen, nearby_screen.offx, nearby_screen.offy);
4499 209961559 }
4500
4501 145284842 static void draw_msgstr(byte layer, BITMAP* dest = nullptr)
4502 {
4503
2/2
✓ Branch 0 taken 32308234 times.
✓ Branch 1 taken 112976608 times.
145284842 if(layer != msgstr_layer) return;
4504
2/2
✓ Branch 0 taken 16132608 times.
✓ Branch 1 taken 16175626 times.
32308234 if(!dest) dest = framebuf;
4505
4506
2/2
✓ Branch 0 taken 1460947 times.
✓ Branch 1 taken 30847287 times.
32308234 if(!(msg_bg_display_buf->clip))
4507 {
4508 1460947 blit_msgstr_bg(dest,0,0,0,playing_field_offset,256,176);
4509 1460947 }
4510
4511
2/2
✓ Branch 0 taken 1460947 times.
✓ Branch 1 taken 30847287 times.
32308234 if(!(msg_portrait_display_buf->clip))
4512 {
4513 1460947 blit_msgstr_prt(dest,0,0,0,playing_field_offset,256,176);
4514 1460947 }
4515
4516
2/2
✓ Branch 0 taken 1487761 times.
✓ Branch 1 taken 30820473 times.
32308234 if(!(msg_txt_display_buf->clip))
4517 {
4518 1487761 blit_msgstr_fg(dest,0,0,0,playing_field_offset,256,176);
4519 1487761 }
4520 145284842 }
4521
4522 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y);
4523
4524 64533480 static void set_draw_screen_clip(BITMAP* bmp)
4525 {
4526 64533480 set_clip_rect(bmp, draw_screen_clip_rect_x1, draw_screen_clip_rect_y1, draw_screen_clip_rect_x2, draw_screen_clip_rect_y2);
4527 64533480 }
4528
4529 17580 static void draw_sprites(BITMAP* dest, set<sprite*, SpriteSorter>& sprite_set, set<sprite*, SpriteSorter>::iterator& it, word upto_z)
4530 {
4531 17580 bool checkz = upto_z != word(-1); // max value represents "infinity" height
4532
6/6
✓ Branch 0 taken 11145 times.
✓ Branch 1 taken 6435 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 6275 times.
✓ Branch 4 taken 12905 times.
✓ Branch 5 taken 4675 times.
17580 if(it == sprite_set.end() || (checkz && (*it)->total_z() >= upto_z))
4533 12905 return; // no sprites to draw remaining
4534 // Just clips sprites if in a repeating, smooth maze.
4535
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 bool do_clip = maze_state.active && maze_state.loopy;
4536
4537
4538
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 if(do_clip)
4539 {
4540 int maze_screen = maze_state.scr->screen;
4541 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4542 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4543 }
4544
6/6
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 32443 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 32283 times.
✓ Branch 4 taken 4675 times.
✓ Branch 5 taken 30698 times.
67816 while(it != sprite_set.end() && (!checkz || (*it)->total_z() < upto_z))
4545 {
4546 30698 sprite* spr = *it;
4547
2/2
✓ Branch 0 taken 27768 times.
✓ Branch 1 taken 2930 times.
30698 if(spr == &Hero) // Draw the Hero
4548 {
4549 2930 decorations.draw2(dest,true);
4550 2930 Hero.draw(dest);
4551 2930 decorations.draw(dest,true);
4552
4553 // Draw enemies holding the Hero directly above the Hero
4554
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 for(int32_t i=0; i<guys.Count(); i++)
4555 {
4556 if(((enemy*)guys.spr(i))->type == eeWALK)
4557 if(((eStalfos*)guys.spr(i))->hashero)
4558 guys.spr(i)->draw(dest);
4559 else if(((enemy*)guys.spr(i))->type == eeWALLM)
4560 if(((eWallM*)guys.spr(i))->hashero)
4561 guys.spr(i)->draw(dest);
4562 }
4563 2930 }
4564
2/2
✓ Branch 0 taken 24838 times.
✓ Branch 1 taken 2930 times.
27768 else if(spr == &mblock2) // Draw the moving pushblock
4565 {
4566 2930 mblock2.draw(dest, -1);
4567 2930 do_primitives(dest, SPLAYER_MOVINGBLOCK);
4568 2930 }
4569
2/4
✓ Branch 0 taken 24838 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24838 times.
24838 else if(enemy* e = dynamic_cast<enemy*>(spr))
4570 {
4571 e->draw(dest);
4572 e->draw2(dest); // used specifically for eGleeok/esGleeok
4573 }
4574 24838 else spr->draw(dest);
4575 30698 ++it;
4576 }
4577
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 if(do_clip)
4578 clear_clip_rect(dest);
4579 17580 }
4580
4581 11991 static void draw_high_darkness(BITMAP* dest)
4582 {
4583 11991 do_primitives(dest, SPLAYER_DARKROOM_UNDER);
4584 11991 set_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
4585
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
4586 {
4587 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
4588 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
4589 }
4590
4591 11991 color_map = trans_table2;
4592
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
4593 {
4594 draw_trans_sprite(dest, darkscr_bmp, 0, 0);
4595 if(get_qr(qr_NEWDARK_TRANS_STACKING))
4596 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
4597 }
4598 else
4599 {
4600 11991 masked_blit(darkscr_bmp, dest, 0, 0, 0, 0, dest->w, dest->h);
4601 11991 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
4602 }
4603 11991 color_map = trans_table;
4604
4605 11991 set_clip_rect(dest, 0, 0, dest->w, dest->h);
4606 11991 do_primitives(dest, SPLAYER_DARKROOM_OVER);
4607 11991 }
4608
4609 16175626 static void draw_screen_post_passive_subscreen(BITMAP* dest, bool any_dark)
4610 {
4611 16175626 draw_msgstr(6, dest);
4612
4613
1/2
✓ Branch 0 taken 16175626 times.
✗ Branch 1 not taken.
16175626 if (get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
4614 draw_msgstr(6, dest);
4615
4616
6/6
✓ Branch 0 taken 1905413 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 453730 times.
✓ Branch 3 taken 1451683 times.
✓ Branch 4 taken 441739 times.
✓ Branch 5 taken 11991 times.
16175626 if (get_qr(qr_NEW_DARKROOM) && !get_qr(qr_NEWDARK_L6) && any_dark)
4617 11991 draw_high_darkness(dest);
4618
4619 16175626 _do_current_ffc_layer(dest, 7);
4620 16175626 draw_msgstr(7, dest);
4621 16175626 }
4622
4623 // Draws to framebuf.
4624 //
4625 // But if drawPassiveSubscreenSeparate is true: framebuf_no_passive_subscreen will also contain all
4626 // draws excluding the passive subscreen.
4627 16133370 void draw_screen(bool showhero, bool runGeneric, bool drawPassiveSubscreenSeparate)
4628 {
4629 16133370 bool classic_draw = get_qr(qr_CLASSIC_DRAWING_ORDER);
4630 16133370 clear_info_bmp();
4631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16133370 times.
16133370 if((GameFlags & (GAMEFLAG_SCRIPTMENU_ACTIVE|GAMEFLAG_F6SCRIPT_ACTIVE))!=0)
4632 {
4633 FFCore.doScriptMenuDraws();
4634 return;
4635 }
4636
4637
2/2
✓ Branch 0 taken 613571 times.
✓ Branch 1 taken 15519799 times.
16133370 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_PRE_DRAW);
4638
4639 16133370 BITMAP* dest = framebuf;
4640 16133370 clear_bitmap(dest);
4641 16133370 clear_clip_rect(dest);
4642
4643 16133370 int32_t cmby2=0;
4644
4645 // Draw some background layers
4646 16133370 clear_bitmap(scrollbuf);
4647
4648 16133370 auto nearby_screens = get_nearby_screens();
4649
4650
2/2
✓ Branch 0 taken 16130440 times.
✓ Branch 1 taken 2930 times.
16133370 if (!classic_draw)
4651 {
4652
2/2
✓ Branch 0 taken 11720 times.
✓ Branch 1 taken 2930 times.
14650 for (int layer = -7; layer <= -4; ++layer)
4653 {
4654
1/2
✓ Branch 0 taken 11720 times.
✗ Branch 1 not taken.
11720 _do_current_ffc_layer(scrollbuf, layer);
4655
2/4
✓ Branch 0 taken 11720 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11720 times.
11720 if (script_drawing_commands.is_dirty(layer))
4656 do_primitives(scrollbuf, layer);
4657 11720 }
4658 2930 }
4659
4660 // Handle layer 2/3 possibly being background layers.
4661
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130440 times.
16133370 if (classic_draw) // weird ordering (-3 > -2)
4662 {
4663
1/2
✓ Branch 0 taken 16130440 times.
✗ Branch 1 not taken.
32397198 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4664 16266758 mapscr* base_scr = screen_handles[0].base_scr;
4665
2/2
✓ Branch 0 taken 16124637 times.
✓ Branch 1 taken 142121 times.
16266758 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4666 142121 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4667 16266758 });
4668
4669 16130440 bool l2bg = XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG);
4670
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 15988319 times.
16130440 if (l2bg)
4671 {
4672
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 do_layer_primitives(scrollbuf, 2);
4673
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 particles.draw(scrollbuf, true, 2);
4674 142121 }
4675
1/2
✓ Branch 0 taken 16130440 times.
✗ Branch 1 not taken.
16130440 _do_current_ffc_layer(scrollbuf, -2);
4676
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 15988319 times.
16130440 if (l2bg)
4677
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 draw_msgstr(2, scrollbuf);
4678 16130440 }
4679
4680
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
32403058 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4681 16269688 mapscr* base_scr = screen_handles[0].base_scr;
4682
2/2
✓ Branch 0 taken 16035124 times.
✓ Branch 1 taken 234564 times.
16269688 if (XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4683 234564 do_layer(scrollbuf, 0, screen_handles[3], offx, offy);
4684 16269688 });
4685
4686
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 15898806 times.
16133370 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4687 {
4688
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 do_layer_primitives(scrollbuf, 3);
4689
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 particles.draw(scrollbuf, true, 3);
4690 234564 }
4691
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 _do_current_ffc_layer(scrollbuf, -3);
4692
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 15898806 times.
16133370 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4693
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 draw_msgstr(3, scrollbuf);
4694
4695
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130440 times.
16133370 if (!classic_draw)
4696 {
4697
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -3);
4698 // Actually use proper ordering (-3 < -2)
4699
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
5860 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4700 2930 mapscr* base_scr = screen_handles[0].base_scr;
4701
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4702 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4703 2930 });
4704
4705 2930 bool l2bg = XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG);
4706
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if (l2bg)
4707 {
4708 do_layer_primitives(scrollbuf, 2);
4709 particles.draw(scrollbuf, true, 2);
4710 }
4711
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 _do_current_ffc_layer(scrollbuf, -2);
4712
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if (l2bg)
4713 draw_msgstr(2, scrollbuf);
4714
4715
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -2);
4716
4717
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 _do_current_ffc_layer(scrollbuf, -1);
4718
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -1);
4719 2930 }
4720
4721 // Draw the main combo screens ("layer 0").
4722
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
32403058 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4723 16269688 mapscr* base_scr = screen_handles[0].base_scr;
4724
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16269688 times.
16269688 if (lenscheck(base_scr, 0))
4725 {
4726 16269688 putscr(base_scr, scrollbuf, offx, offy + playing_field_offset);
4727 16269688 }
4728 16269688 });
4729
4730
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16133370 times.
16133370 if (lenscheck(hero_scr, 0))
4731 {
4732
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15667321 times.
16133370 if(!get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4733
3/4
✓ Branch 0 taken 466049 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4136 times.
✓ Branch 3 taken 461913 times.
470185 if(mblock2.draw(scrollbuf,0))
4734
1/2
✓ Branch 0 taken 4136 times.
✗ Branch 1 not taken.
4136 do_primitives(scrollbuf, SPLAYER_MOVINGBLOCK);
4735 16133370 }
4736
4737 // Lens hints, then primitives, then particles.
4738
6/10
✓ Branch 0 taken 16123341 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 16123341 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 16123341 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5876 times.
✓ Branch 9 taken 4153 times.
16133370 if((lensclk || (get_debug() && zc_getkey(KEY_L))) && !get_qr(qr_OLDLENSORDER))
4739 {
4740
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 draw_lens_under(scrollbuf, false);
4741
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4742 5876 }
4743
4744
2/4
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16133370 times.
✗ Branch 3 not taken.
16133370 if(show_layers[0] && lenscheck(hero_scr,0))
4745
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 do_primitives(scrollbuf, 0);
4746
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 particles.draw(scrollbuf, true, 0);
4747
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 _do_current_ffc_layer(scrollbuf, 0);
4748
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 draw_msgstr(0, scrollbuf);
4749
4750
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 set_draw_screen_clip(scrollbuf);
4751
4752 16133370 bool hero_draw_done = false;
4753
4/6
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16098618 times.
✓ Branch 3 taken 34752 times.
✓ Branch 4 taken 16098618 times.
✗ Branch 5 not taken.
16133370 bool is_cave_walking = ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom));
4754
2/2
✓ Branch 0 taken 343259 times.
✓ Branch 1 taken 15790111 times.
16133370 if(!(get_qr(qr_LAYER12UNDERCAVE)))
4755 {
4756
4/4
✓ Branch 0 taken 15788233 times.
✓ Branch 1 taken 1878 times.
✓ Branch 2 taken 88384 times.
✓ Branch 3 taken 15699849 times.
15790111 if(showhero && is_cave_walking)
4757 {
4758 88384 hero_draw_done = true;
4759
3/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 34752 times.
88384 if(Hero.getAction()==climbcovertop)
4760 {
4761 34752 cmby2=16;
4762 34752 }
4763
2/4
✓ Branch 0 taken 53632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53632 times.
53632 else if(Hero.getAction()==climbcoverbottom)
4764 {
4765 53632 cmby2=-16;
4766 53632 }
4767
4768
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw2(scrollbuf,true);
4769
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 Hero.draw(scrollbuf);
4770
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw(scrollbuf,true);
4771
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccx = (int32_t)Hero.getClimbCoverX();
4772
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccy = (int32_t)Hero.getClimbCoverY();
4773
4774
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4775
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4776
4777
4/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✓ Branch 5 taken 73152 times.
88384 if(int32_t(Hero.getX())&15)
4778 {
4779
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4780
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4781 15232 }
4782 88384 }
4783 15790111 }
4784
4785
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 16133370 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16133370 if (get_qr(qr_HERO_DIVE_UNDER_LAYER_1) && Hero.isDiving())
4786 {
4787 Hero.draw_under(scrollbuf);
4788 decorations.draw2(scrollbuf,true);
4789 Hero.draw(scrollbuf);
4790 decorations.draw(scrollbuf,true);
4791 hero_draw_done = true;
4792 }
4793
4794
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
32403058 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4795 16269688 do_layer(scrollbuf, 0, screen_handles[1], offx, offy); // LAYER 1
4796 16269688 });
4797
4798
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 do_layer_primitives(scrollbuf, 1);
4799
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 particles.draw(scrollbuf, true, 1);
4800
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 _do_current_ffc_layer(scrollbuf, 1);
4801
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 draw_msgstr(1, scrollbuf);
4802
4803 // Handle layer 2 NOT being used as background layers.
4804
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
32403058 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4805 16269688 mapscr* base_scr = screen_handles[0].base_scr;
4806
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 16127567 times.
16269688 if (!XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4807 16127567 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4808 16269688 });
4809
4810
2/2
✓ Branch 0 taken 15991249 times.
✓ Branch 1 taken 142121 times.
16133370 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4811 {
4812
1/2
✓ Branch 0 taken 15991249 times.
✗ Branch 1 not taken.
15991249 do_layer_primitives(scrollbuf, 2);
4813
1/2
✓ Branch 0 taken 15991249 times.
✗ Branch 1 not taken.
15991249 particles.draw(scrollbuf, true, 2);
4814 15991249 }
4815
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 _do_current_ffc_layer(scrollbuf, 2);
4816
2/2
✓ Branch 0 taken 15991249 times.
✓ Branch 1 taken 142121 times.
16133370 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4817
1/2
✓ Branch 0 taken 15991249 times.
✗ Branch 1 not taken.
15991249 draw_msgstr(2, scrollbuf);
4818
4819
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 do_primitives(scrollbuf, SPLAYER_FFC_DRAW);
4820
4821
2/2
✓ Branch 0 taken 15790111 times.
✓ Branch 1 taken 343259 times.
16133370 if(get_qr(qr_LAYER12UNDERCAVE))
4822 {
4823
2/4
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 343259 times.
343259 if(showhero && is_cave_walking)
4824 {
4825 hero_draw_done = true;
4826 if(Hero.getAction()==climbcovertop)
4827 {
4828 cmby2=16;
4829 }
4830 else if(Hero.getAction()==climbcoverbottom)
4831 {
4832 cmby2=-16;
4833 }
4834
4835 decorations.draw2(scrollbuf,true);
4836 Hero.draw(scrollbuf);
4837 decorations.draw(scrollbuf,true);
4838 int32_t ccx = (int32_t)(Hero.getClimbCoverX());
4839 int32_t ccy = (int32_t)(Hero.getClimbCoverY());
4840
4841 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4842 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4843
4844 if(int32_t(Hero.getX())&15)
4845 {
4846 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4847 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4848 }
4849 }
4850 343259 }
4851
4852
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15667321 times.
16133370 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4853 {
4854
1/2
✓ Branch 0 taken 15667321 times.
✗ Branch 1 not taken.
31470960 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4855 15803639 do_layer(scrollbuf, -2, screen_handles[0], offx, offy); // push blocks!
4856
2/2
✓ Branch 0 taken 14478915 times.
✓ Branch 1 taken 1324724 times.
15803639 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
4857 {
4858 1324724 do_layer(scrollbuf, -2, screen_handles[1], offx, offy); // push blocks!
4859 1324724 do_layer(scrollbuf, -2, screen_handles[2], offx, offy); // push blocks!
4860 1324724 }
4861 15803639 });
4862
4863
1/2
✓ Branch 0 taken 15667321 times.
✗ Branch 1 not taken.
15667321 do_primitives(scrollbuf, SPLAYER_PUSHBLOCK);
4864 15667321 }
4865
4866 // Show walkflags cheat
4867
2/4
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16133370 times.
16133370 if (show_walkflags || show_effectflags)
4868 {
4869 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4870 do_walkflags(screen_handles, offx, offy);
4871 do_effectflags(screen_handles[0].base_scr, offx, offy);
4872 });
4873
4874 do_walkflags(0, 0);
4875 }
4876
4877
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 putscrdoors(nearby_screens, scrollbuf, 0, playing_field_offset);
4878
4879 // Lens hints, doors etc.
4880
4/8
✓ Branch 0 taken 16123341 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 16123341 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 16123341 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
16133370 if(lensclk || (get_debug() && zc_getkey(KEY_L)))
4881 {
4882
2/2
✓ Branch 0 taken 4153 times.
✓ Branch 1 taken 5876 times.
10029 if(get_qr(qr_OLDLENSORDER))
4883 {
4884
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 draw_lens_under(scrollbuf, false);
4885
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4886 4153 }
4887
4888
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 draw_lens_under(scrollbuf, true);
4889
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_2);
4890 10029 }
4891
4892 // Blit those layers onto dest (framebuf)
4893
4894
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 set_draw_screen_clip(dest);
4895
4896
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 blit(scrollbuf, dest, 0, 0, 0, 0, 256, 232);
4897
4898 // After this point, scrollbuf is no longer drawn to - so things like dosubscr have access to a "partially rendered" frame.
4899 // I think only used for COOLSCROLL==0? Seems like a silly feature...
4900
4901 // Draw the subscreen, without clipping
4902
2/2
✓ Branch 0 taken 9251384 times.
✓ Branch 1 taken 6881986 times.
16133370 if(!get_qr(qr_SUBSCREENOVERSPRITES))
4903 {
4904 9251384 bool dotime = false;
4905
4/6
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3412853 times.
✓ Branch 3 taken 5838531 times.
✓ Branch 4 taken 3412853 times.
✗ Branch 5 not taken.
9251384 if (replay_version_check(22)) dotime = game->should_show_time();
4906
1/2
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
9251384 put_passive_subscr(dest, 0, 0, dotime, sspUP);
4907 9251384 }
4908
4909 // Draw some sprites onto dest
4910
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 set_clip_rect(dest,0,0,256,232);
4911
4912
2/2
✓ Branch 0 taken 99496 times.
✓ Branch 1 taken 16033874 times.
16133370 if(!(pricesdisplaybuf->clip))
4913 {
4914
1/2
✓ Branch 0 taken 99496 times.
✗ Branch 1 not taken.
99496 masked_blit(pricesdisplaybuf,dest,0,0,0,playing_field_offset,256,176);
4915 99496 }
4916
4917
5/6
✓ Branch 0 taken 16087744 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16081416 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16133370 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4918 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
4919
4920
4/4
✓ Branch 0 taken 16131492 times.
✓ Branch 1 taken 1878 times.
✓ Branch 2 taken 16043108 times.
✓ Branch 3 taken 88384 times.
16133370 if(showhero && !hero_draw_done)
4921 {
4922
1/2
✓ Branch 0 taken 16043108 times.
✗ Branch 1 not taken.
16043108 Hero.draw_under(dest);
4923
4924
3/4
✓ Branch 0 taken 16043108 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141385 times.
✓ Branch 3 taken 15901723 times.
16043108 if(Hero.isSwimming())
4925 {
4926
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw2(dest,true);
4927
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 Hero.draw(dest);
4928
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw(dest,true);
4929 141385 hero_draw_done = true;
4930 141385 }
4931 16043108 }
4932
4933 16133370 set<sprite*, SpriteSorter> sorted_sprites;
4934 16133370 vector<sprite*> temp_sprites;
4935 16133370 std::function<bool(sprite&)> add_sprite = [&](sprite& spr)
4936 {
4937 sorted_sprites.insert(&spr);
4938 return false;
4939 };
4940
4941
2/2
✓ Branch 0 taken 16130440 times.
✓ Branch 1 taken 2930 times.
16133370 if (classic_draw)
4942 {
4943
2/2
✓ Branch 0 taken 26095 times.
✓ Branch 1 taken 16104345 times.
16130440 if(drawguys)
4944 {
4945
4/4
✓ Branch 0 taken 1982674 times.
✓ Branch 1 taken 14121671 times.
✓ Branch 2 taken 991089 times.
✓ Branch 3 taken 991585 times.
16104345 if(get_qr(qr_NOFLICKER) || (frame&1))
4946 {
4947 // Just clips sprites if in a repeating, smooth maze.
4948
2/2
✓ Branch 0 taken 15103546 times.
✓ Branch 1 taken 9214 times.
15112760 bool do_clip = maze_state.active && maze_state.loopy;
4949
4950
1/2
✓ Branch 0 taken 15112760 times.
✗ Branch 1 not taken.
15112760 if(!get_qr(qr_OLD_WEAPON_DRAW_ANIMATE_TIMING))
4951 {
4952 if (do_clip)
4953 {
4954 Ewpns.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS));
4955 Lwpns.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS));
4956 }
4957 else
4958 {
4959 Ewpns.drawshadow(dest,get_qr(qr_TRANSSHADOWS),true);
4960 Lwpns.drawshadow(dest,get_qr(qr_TRANSSHADOWS),true);
4961 }
4962 }
4963
3/4
✓ Branch 0 taken 24917834 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9805074 times.
✓ Branch 3 taken 15112760 times.
24917834 for(int32_t i=0; i<Ewpns.Count(); i++)
4964 {
4965
3/4
✓ Branch 0 taken 9805074 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 250942 times.
✓ Branch 3 taken 9554132 times.
9805074 if(((weapon *)Ewpns.spr(i))->behind)
4966
2/4
✓ Branch 0 taken 250942 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 250942 times.
✗ Branch 3 not taken.
250942 Ewpns.spr(i)->draw(dest);
4967 9805074 }
4968
1/2
✓ Branch 0 taken 15112760 times.
✗ Branch 1 not taken.
15112760 do_primitives(dest, SPLAYER_EWEAP_BEHIND_DRAW);
4969
4970
3/4
✓ Branch 0 taken 21296751 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6183991 times.
✓ Branch 3 taken 15112760 times.
21296751 for(int32_t i=0; i<Lwpns.Count(); i++)
4971 {
4972
3/4
✓ Branch 0 taken 6183991 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1206996 times.
✓ Branch 3 taken 4976995 times.
6183991 if(((weapon *)Lwpns.spr(i))->behind)
4973
2/4
✓ Branch 0 taken 1206996 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1206996 times.
✗ Branch 3 not taken.
1206996 Lwpns.spr(i)->draw(dest);
4974 6183991 }
4975
1/2
✓ Branch 0 taken 15112760 times.
✗ Branch 1 not taken.
15112760 do_primitives(dest, SPLAYER_LWEAP_BEHIND_DRAW);
4976
4977
6/6
✓ Branch 0 taken 10375896 times.
✓ Branch 1 taken 4736864 times.
✓ Branch 2 taken 1348300 times.
✓ Branch 3 taken 9027596 times.
✓ Branch 4 taken 674011 times.
✓ Branch 5 taken 674289 times.
15112760 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4978 {
4979
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 9697949 times.
9701607 if (do_clip)
4980
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS)!=0);
4981 else
4982
1/2
✓ Branch 0 taken 9697949 times.
✗ Branch 1 not taken.
9697949 guys.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0,true);
4983 9701607 }
4984
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109102 times.
15112760 if (do_clip)
4985
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.draw_smooth_maze(dest);
4986 else
4987
1/2
✓ Branch 0 taken 15109102 times.
✗ Branch 1 not taken.
15109102 guys.draw(dest,true);
4988
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109102 times.
15112760 if (do_clip)
4989 {
4990 3658 int maze_screen = maze_state.scr->screen;
4991
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4992
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4993 3658 }
4994
1/2
✓ Branch 0 taken 15112760 times.
✗ Branch 1 not taken.
15112760 do_primitives(dest, SPLAYER_NPC_DRAW);
4995
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109102 times.
15112760 if (do_clip)
4996
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(dest);
4997
4998
1/2
✓ Branch 0 taken 15112760 times.
✗ Branch 1 not taken.
15112760 chainlinks.draw(dest,true);
4999
1/2
✓ Branch 0 taken 15112760 times.
✗ Branch 1 not taken.
15112760 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5000 //Lwpns.draw(dest,true);
5001
5002
3/4
✓ Branch 0 taken 24917834 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9805074 times.
✓ Branch 3 taken 15112760 times.
24917834 for(int32_t i=0; i<Ewpns.Count(); i++)
5003 {
5004
3/4
✓ Branch 0 taken 9805074 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9554132 times.
✓ Branch 3 taken 250942 times.
9805074 if(!((weapon *)Ewpns.spr(i))->behind)
5005
2/4
✓ Branch 0 taken 9554132 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9554132 times.
✗ Branch 3 not taken.
9554132 Ewpns.spr(i)->draw(dest);
5006 9805074 }
5007
1/2
✓ Branch 0 taken 15112760 times.
✗ Branch 1 not taken.
15112760 do_primitives(dest, SPLAYER_EWEAP_FRONT_DRAW);
5008
5009
3/4
✓ Branch 0 taken 21296751 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6183991 times.
✓ Branch 3 taken 15112760 times.
21296751 for(int32_t i=0; i<Lwpns.Count(); i++)
5010 {
5011
3/4
✓ Branch 0 taken 6183991 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4976995 times.
✓ Branch 3 taken 1206996 times.
6183991 if(!((weapon *)Lwpns.spr(i))->behind)
5012
2/4
✓ Branch 0 taken 4976995 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4976995 times.
✗ Branch 3 not taken.
4976995 Lwpns.spr(i)->draw(dest);
5013 6183991 }
5014
1/2
✓ Branch 0 taken 15112760 times.
✗ Branch 1 not taken.
15112760 do_primitives(dest, SPLAYER_LWEAP_FRONT_DRAW);
5015
5016
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109102 times.
15112760 if (do_clip)
5017
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 items.draw_smooth_maze(dest);
5018 else
5019
1/2
✓ Branch 0 taken 15109102 times.
✗ Branch 1 not taken.
15109102 items.draw(dest,true);
5020
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109102 times.
15112760 if (do_clip)
5021 {
5022 3658 int maze_screen = maze_state.scr->screen;
5023
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
5024
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
5025 3658 }
5026
1/2
✓ Branch 0 taken 15112760 times.
✗ Branch 1 not taken.
15112760 do_primitives(dest, SPLAYER_ITEMSPRITE_DRAW);
5027
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15109102 times.
15112760 if (do_clip)
5028
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(dest);
5029 15112760 }
5030 else
5031 {
5032
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
5033 {
5034
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✓ Branch 3 taken 496727 times.
505372 if(((weapon *)Ewpns.spr(i))->behind)
5035
2/4
✓ Branch 0 taken 8645 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
8645 Ewpns.spr(i)->draw(dest);
5036 505372 }
5037
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_EWEAP_BEHIND_DRAW);
5038
5039
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
5040 {
5041
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 231146 times.
231146 if(((weapon *)Lwpns.spr(i))->behind)
5042 Lwpns.spr(i)->draw(dest);
5043 231146 }
5044
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_LWEAP_BEHIND_DRAW);
5045
5046
3/4
✓ Branch 0 taken 228620 times.
✓ Branch 1 taken 762965 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228620 times.
991585 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5047 {
5048
1/2
✓ Branch 0 taken 228620 times.
✗ Branch 1 not taken.
228620 guys.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0,true);
5049 228620 }
5050
5051
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 items.draw(dest,false);
5052
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_ITEMSPRITE_DRAW);
5053
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 chainlinks.draw(dest,false);
5054
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5055 //Lwpns.draw(dest,false);
5056
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 guys.draw(dest,false);
5057
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_NPC_DRAW);
5058
5059
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
5060 {
5061
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✓ Branch 3 taken 8645 times.
505372 if(!((weapon *)Ewpns.spr(i))->behind)
5062 {
5063
2/4
✓ Branch 0 taken 496727 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✗ Branch 3 not taken.
496727 Ewpns.spr(i)->draw(dest);
5064 496727 }
5065 505372 }
5066
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_EWEAP_FRONT_DRAW);
5067
5068
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
5069 {
5070
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 if(!((weapon *)Lwpns.spr(i))->behind)
5071 {
5072
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 Lwpns.spr(i)->draw(dest);
5073 231146 }
5074 231146 }
5075
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_LWEAP_FRONT_DRAW);
5076 }
5077
5078
1/2
✓ Branch 0 taken 16104345 times.
✗ Branch 1 not taken.
16104345 guys.draw2(dest,true);
5079 16104345 }
5080
5081
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16130440 times.
16130440 if(mirror_portal.destdmap > -1)
5082 mirror_portal.draw(dest);
5083
1/2
✓ Branch 0 taken 16130440 times.
✗ Branch 1 not taken.
16130440 portals.draw(dest,true);
5084
5085
4/4
✓ Branch 0 taken 16128562 times.
✓ Branch 1 taken 1878 times.
✓ Branch 2 taken 88384 times.
✓ Branch 3 taken 16040178 times.
16130440 if(showhero && !is_cave_walking)
5086 {
5087
2/2
✓ Branch 0 taken 15580545 times.
✓ Branch 1 taken 459633 times.
16040178 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
5088 {
5089
1/2
✓ Branch 0 taken 15580545 times.
✗ Branch 1 not taken.
15580545 mblock2.draw(dest,-1);
5090
1/2
✓ Branch 0 taken 15580545 times.
✗ Branch 1 not taken.
15580545 do_primitives(dest, SPLAYER_MOVINGBLOCK);
5091 15580545 }
5092
2/2
✓ Branch 0 taken 15898793 times.
✓ Branch 1 taken 141385 times.
16040178 if(!hero_draw_done)
5093 {
5094
8/12
✓ Branch 0 taken 15898793 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15898793 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15879623 times.
✓ Branch 5 taken 19170 times.
✓ Branch 6 taken 15879623 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15879623 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1370 times.
✓ Branch 11 taken 15897423 times.
15898793 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5095 {
5096
2/2
✓ Branch 0 taken 18485 times.
✓ Branch 1 taken 15880308 times.
15898793 Hero.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0);
5097 18485 }
5098
5099
6/8
✓ Branch 0 taken 15898793 times.
✓ Branch 1 taken 15880308 times.
✓ Branch 2 taken 15898793 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15898793 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15884729 times.
✓ Branch 7 taken 14064 times.
18485 if(Hero.getZ() <= (zfix)zinit.jump_hero_layer_threshold)
5100 {
5101
1/2
✓ Branch 0 taken 15884729 times.
✗ Branch 1 not taken.
15884729 decorations.draw2(dest,true);
5102
1/2
✓ Branch 0 taken 15884729 times.
✗ Branch 1 not taken.
15884729 Hero.draw(dest);
5103
1/2
✓ Branch 0 taken 15884729 times.
✗ Branch 1 not taken.
15884729 decorations.draw(dest,true);
5104 15884729 hero_draw_done = true;
5105 15884729 }
5106 15898793 }
5107 16040178 }
5108
5109
3/4
✓ Branch 0 taken 56548008 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40417568 times.
✓ Branch 3 taken 16130440 times.
56548008 for(int32_t i=0; i<guys.Count(); i++)
5110 {
5111
3/4
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16520322 times.
✓ Branch 3 taken 23897246 times.
40417568 if(((enemy*)guys.spr(i))->type == eeWALK)
5112 {
5113
3/4
✓ Branch 0 taken 16520322 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7965 times.
✓ Branch 3 taken 16512357 times.
16520322 if(((eStalfos*)guys.spr(i))->hashero)
5114 {
5115
2/4
✓ Branch 0 taken 7965 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7965 times.
✗ Branch 3 not taken.
7965 guys.spr(i)->draw(dest);
5116 7965 }
5117 16520322 }
5118
5119
3/4
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 507162 times.
✓ Branch 3 taken 39910406 times.
40417568 if(((enemy*)guys.spr(i))->type == eeWALLM)
5120 {
5121
3/4
✓ Branch 0 taken 507162 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✓ Branch 3 taken 505833 times.
507162 if(((eWallM*)guys.spr(i))->hashero)
5122 {
5123
2/4
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
1329 guys.spr(i)->draw(dest);
5124 1329 }
5125 507162 }
5126
5127
11/20
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40417568 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40417568 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 40417568 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 40417568 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 40417568 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 40417568 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 40417568 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 40417568 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1523506 times.
✓ Branch 19 taken 38894062 times.
40417568 if(guys.spr(i)->z+guys.spr(i)->fakez > Hero.getZ()+Hero.getFakeZ())
5128 {
5129 //Jumping enemies in front of Hero.
5130
2/4
✓ Branch 0 taken 1523506 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1523506 times.
✗ Branch 3 not taken.
1523506 guys.spr(i)->draw(dest);
5131 1523506 }
5132
1/2
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
40417568 do_primitives(dest, SPLAYER_NPC_ABOVEPLAYER_DRAW);
5133 40417568 }
5134 16130440 }
5135 else
5136 {
5137
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if(drawguys)
5138 {
5139
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 chainlinks.forEach(add_sprite);
5140
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
5860 bool show_enemy_shadows = (get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1));
5141 25837 auto add_spr_shadow = [&](sprite& spr)
5142 {
5143 22907 sorted_sprites.insert(&spr);
5144
3/4
✓ Branch 0 taken 1291 times.
✓ Branch 1 taken 21616 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1291 times.
22907 if(spr.total_z() > 0 && spr.can_drawshadow())
5145 {
5146
1/2
✓ Branch 0 taken 1291 times.
✗ Branch 1 not taken.
1291 tempsprite_shadow* shadow = new tempsprite_shadow(&spr);
5147 1291 sorted_sprites.insert(shadow);
5148 1291 temp_sprites.push_back(shadow);
5149 1291 }
5150 22907 return false;
5151 };
5152
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 Lwpns.forEach(add_spr_shadow);
5153
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 Ewpns.forEach(add_spr_shadow);
5154
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 items.forEach(add_spr_shadow);
5155
4/14
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2930 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2930 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2930 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2930 guys.forEach(show_enemy_shadows ? add_spr_shadow : add_sprite);
5156 2930 }
5157
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 if(showhero && !hero_draw_done)
5158 {
5159
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 sorted_sprites.insert(&Hero);
5160
9/14
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2290 times.
✓ Branch 5 taken 640 times.
✓ Branch 6 taken 2290 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2290 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2930 times.
✓ Branch 12 taken 2290 times.
✓ Branch 13 taken 2290 times.
2930 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5161 {
5162
3/4
✓ Branch 0 taken 640 times.
✓ Branch 1 taken 4580 times.
✓ Branch 2 taken 640 times.
✗ Branch 3 not taken.
5220 tempsprite_shadow* shadow = new tempsprite_shadow(&Hero);
5163
1/2
✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
640 sorted_sprites.insert(shadow);
5164
1/2
✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
640 temp_sprites.push_back(shadow);
5165 640 }
5166 2930 }
5167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if(mirror_portal.destdmap > -1)
5168 sorted_sprites.insert(&mirror_portal);
5169
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 portals.forEach(add_sprite);
5170
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
5171
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 sorted_sprites.insert(&mblock2);
5172 }
5173 16133370 auto sprite_it = sorted_sprites.begin();
5174
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130440 times.
16133370 if (!classic_draw)
5175
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_GROUND]);
5176
5177 // Draw some layers onto dest
5178
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 set_draw_screen_clip(dest);
5179
5/6
✓ Branch 0 taken 16087744 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16081416 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16133370 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5180 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5181
5182 // Handle layer 3 NOT being used as background layers.
5183
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
32403058 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5184 16269688 mapscr* base_scr = screen_handles[0].base_scr;
5185
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 16035124 times.
16269688 if (!XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5186 16035124 do_layer(dest, 0, screen_handles[3], offx, offy);
5187 16269688 });
5188
5189
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130440 times.
16133370 if (!classic_draw)
5190
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_3]);
5191
5192
2/2
✓ Branch 0 taken 15898806 times.
✓ Branch 1 taken 234564 times.
16133370 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5193 {
5194
1/2
✓ Branch 0 taken 15898806 times.
✗ Branch 1 not taken.
15898806 do_layer_primitives(dest, 3);
5195
1/2
✓ Branch 0 taken 15898806 times.
✗ Branch 1 not taken.
15898806 particles.draw(dest, true, 3);
5196 15898806 }
5197
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 _do_current_ffc_layer(dest, 3);
5198
2/2
✓ Branch 0 taken 15898806 times.
✓ Branch 1 taken 234564 times.
16133370 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5199
1/2
✓ Branch 0 taken 15898806 times.
✗ Branch 1 not taken.
15898806 draw_msgstr(3);
5200
5201
5202
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
32403058 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5203 16269688 do_layer(dest, 0, screen_handles[4], offx, offy);
5204 16269688 });
5205
5206
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130440 times.
16133370 if (!classic_draw)
5207
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_4]);
5208
5209
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 do_layer_primitives(dest, 4);
5210
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 particles.draw(dest, true, 4);
5211
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 _do_current_ffc_layer(dest, 4);
5212
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 draw_msgstr(4);
5213
5214
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
32403058 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5215 16269688 do_layer(dest, -1, screen_handles[0], offx, offy);
5216
2/2
✓ Branch 0 taken 14402748 times.
✓ Branch 1 taken 1866940 times.
16269688 if (get_qr(qr_OVERHEAD_COMBOS_L1_L2))
5217 {
5218 1866940 do_layer(dest, -1, screen_handles[1], offx, offy);
5219 1866940 do_layer(dest, -1, screen_handles[2], offx, offy);
5220 1866940 }
5221 16269688 });
5222
5223
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 do_primitives(dest, SPLAYER_OVERHEAD_CMB);
5224
5225 // Draw some flying sprites onto dest
5226
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 clear_clip_rect(dest);
5227
5/6
✓ Branch 0 taken 16087744 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16081416 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16133370 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5228 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5229
5230
2/2
✓ Branch 0 taken 16130440 times.
✓ Branch 1 taken 2930 times.
16133370 if (classic_draw)
5231 {
5232 //Jumping Hero and jumping enemies are drawn on this layer.
5233
5/8
✓ Branch 0 taken 16130440 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16130440 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16130440 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14064 times.
✓ Branch 7 taken 16116376 times.
16130440 if(Hero.getZ() > (zfix)zinit.jump_hero_layer_threshold)
5234 {
5235
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw2(dest,false);
5236
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 Hero.draw(dest);
5237
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 chainlinks.draw(dest,true);
5238
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5239
5240
3/4
✓ Branch 0 taken 16806 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✓ Branch 3 taken 14064 times.
16806 for(int32_t i=0; i<Lwpns.Count(); i++)
5241 {
5242
9/16
✓ Branch 0 taken 2742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2742 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2742 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2742 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2742 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 239 times.
✓ Branch 15 taken 2503 times.
2742 if(Lwpns.spr(i)->z+Lwpns.spr(i)->fakez > (zfix)zinit.jump_hero_layer_threshold)
5243 {
5244
2/4
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 Lwpns.spr(i)->draw(dest);
5245 239 }
5246 2742 }
5247
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(dest, SPLAYER_LWEAP_ABOVE_DRAW);
5248
5249
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw(dest,false);
5250 14064 }
5251
5252
5/6
✓ Branch 0 taken 3872571 times.
✓ Branch 1 taken 12257869 times.
✓ Branch 2 taken 44341460 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32083591 times.
✓ Branch 5 taken 12257869 times.
48214031 if(!get_qr(qr_ENEMIESZAXIS)) for(int32_t i=0; i<guys.Count(); i++)
5253 {
5254
13/22
✓ Branch 0 taken 32083591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32083591 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27177493 times.
✓ Branch 5 taken 4906098 times.
✓ Branch 6 taken 27177493 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27177493 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27177493 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27177493 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27177493 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27177493 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27177493 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6568 times.
✓ Branch 21 taken 27170925 times.
32083591 if((isflier(guys.spr(i)->id)) || (guys.spr(i)->z+guys.spr(i)->fakez) > (zfix)zinit.jump_hero_layer_threshold)
5255 {
5256
2/4
✓ Branch 0 taken 4912666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4912666 times.
✗ Branch 3 not taken.
4912666 guys.spr(i)->draw(dest);
5257 4912666 }
5258 44341460 }
5259 else
5260 {
5261
3/4
✓ Branch 0 taken 12206548 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8333977 times.
✓ Branch 3 taken 3872571 times.
12206548 for(int32_t i=0; i<guys.Count(); i++)
5262 {
5263
13/22
✓ Branch 0 taken 8333977 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8333977 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6997572 times.
✓ Branch 5 taken 1336405 times.
✓ Branch 6 taken 6997572 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6997572 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6997572 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6478745 times.
✓ Branch 13 taken 518827 times.
✓ Branch 14 taken 6478745 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 6478745 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 6478745 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 6478745 times.
8333977 if((isflier(guys.spr(i)->id)) || guys.spr(i)->z > 0 || guys.spr(i)->fakez > 0)
5264 {
5265
2/4
✓ Branch 0 taken 1855232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1855232 times.
✗ Branch 3 not taken.
1855232 guys.spr(i)->draw(dest);
5266 1855232 }
5267 8333977 }
5268 }
5269
1/2
✓ Branch 0 taken 16130440 times.
✗ Branch 1 not taken.
16130440 do_primitives(dest, SPLAYER_NPC_AIRBORNE_DRAW);
5270 16130440 }
5271
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 else draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_OVERHEAD]);
5272
5273 // Draw the Moving Fairy above layer 3
5274
3/4
✓ Branch 0 taken 19457506 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3324136 times.
✓ Branch 3 taken 16133370 times.
19457506 for(int32_t i=0; i<items.Count(); i++)
5275
6/8
✓ Branch 0 taken 3324136 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 70250 times.
✓ Branch 3 taken 3253886 times.
✓ Branch 4 taken 70250 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60536 times.
✓ Branch 7 taken 9714 times.
3384672 if(itemsbuf[items.spr(i)->id].type == itype_fairy && itemsbuf[items.spr(i)->id].misc3)
5276
2/4
✓ Branch 0 taken 60536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60536 times.
✗ Branch 3 not taken.
60536 items.spr(i)->draw(dest);
5277
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 do_primitives(dest, SPLAYER_FAIRYITEM_DRAW);
5278
5279 // Draw some layers onto dest
5280
5281
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 set_draw_screen_clip(dest);
5282
5283
2/2
✓ Branch 0 taken 16119018 times.
✓ Branch 1 taken 14352 times.
16133370 if (lightbeam_present)
5284 {
5285 14352 color_map = trans_table2;
5286
2/2
✓ Branch 0 taken 13114 times.
✓ Branch 1 taken 1238 times.
14352 if(get_qr(qr_LIGHTBEAM_TRANSPARENT))
5287
1/2
✓ Branch 0 taken 13114 times.
✗ Branch 1 not taken.
13114 draw_trans_sprite(dest, lightbeam_bmp, 0, playing_field_offset);
5288 else
5289
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 masked_blit(lightbeam_bmp, dest, 0, 0, 0, playing_field_offset, 256, 176);
5290 14352 color_map = trans_table;
5291 14352 }
5292
5293
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
32403058 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5294 16269688 do_layer(dest, 0, screen_handles[5], offx, offy);
5295 16269688 });
5296
5297
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130440 times.
16133370 if (!classic_draw)
5298
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_5]);
5299
5300
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 do_layer_primitives(dest, 5);
5301
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 particles.draw(dest, true, 5);
5302
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 _do_current_ffc_layer(dest, 5);
5303
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 draw_msgstr(5);
5304
5305
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 _do_current_ffc_layer(dest, -1000); // 'overhead' freeform combos
5306
5307
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 do_primitives(dest, SPLAYER_OVERHEAD_FFC);
5308
5309
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
32403058 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5310 16269688 do_layer(dest, 0, screen_handles[6], offx, offy);
5311 16269688 });
5312
5313
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16130440 times.
16133370 if (!classic_draw)
5314
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, word(-1));
5315
5316
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 do_layer_primitives(dest, 6);
5317
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 particles.draw(dest, true, 6);
5318
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 _do_current_ffc_layer(dest, 6);
5319
5320 16133370 bool any_dark = false;
5321
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
32403058 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5322 16269688 mapscr* base_scr = screen_handles[0].scr;
5323 16269688 any_dark |= is_dark(base_scr);
5324 16269688 });
5325
5326 // Handle low drawn darkness
5327
4/4
✓ Branch 0 taken 1863157 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 1516258 times.
✓ Branch 3 taken 346899 times.
16133370 if(get_qr(qr_NEW_DARKROOM) && any_dark)
5328 {
5329
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
700032 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5330 353133 mapscr* base_scr = screen_handles[0].scr;
5331 353133 calc_darkroom_combos(base_scr, offx, offy + playing_field_offset);
5332 353133 calc_darkroom_ffcs(base_scr, 0, playing_field_offset);
5333 353133 });
5334
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
346899 if(showhero)
5335
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
346899 Hero.calc_darkroom_hero(0, -playing_field_offset);
5336
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
700032 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5337 353133 mapscr* base_scr = screen_handles[0].scr;
5338
2/2
✓ Branch 0 taken 348403 times.
✓ Branch 1 taken 4730 times.
353133 if (!is_dark(base_scr))
5339 {
5340 4730 offy += playing_field_offset;
5341 4730 rectfill(darkscr_bmp, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5342 4730 rectfill(darkscr_bmp_trans, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5343 4730 }
5344 353133 });
5345 346899 }
5346
5347 //Darkroom if under the subscreen
5348
6/6
✓ Branch 0 taken 1863157 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 1409427 times.
✓ Branch 3 taken 453730 times.
✓ Branch 4 taken 334908 times.
✓ Branch 5 taken 1074519 times.
16133370 if(get_qr(qr_NEW_DARKROOM) && get_qr(qr_NEWDARK_L6) && any_dark)
5349 {
5350
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 do_primitives(dest, SPLAYER_DARKROOM_UNDER);
5351
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 set_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5352
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 334908 times.
334908 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5353 {
5354 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5355 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5356 }
5357
5358 334908 color_map = trans_table2;
5359
2/2
✓ Branch 0 taken 15523 times.
✓ Branch 1 taken 319385 times.
334908 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5360 {
5361
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 draw_trans_sprite(dest, darkscr_bmp, 0, 0);
5362
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5363
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
5364 15523 }
5365 else
5366 {
5367
1/2
✓ Branch 0 taken 319385 times.
✗ Branch 1 not taken.
319385 masked_blit(darkscr_bmp, dest, 0, 0, 0, 0, dest->w, dest->h);
5368
1/2
✓ Branch 0 taken 319385 times.
✗ Branch 1 not taken.
319385 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
5369 }
5370 334908 color_map = trans_table;
5371
5372
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 set_clip_rect(dest, 0, 0, dest->w, dest->h);
5373
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 do_primitives(dest, SPLAYER_DARKROOM_OVER);
5374 334908 }
5375
5376
3/6
✓ Branch 0 taken 51954 times.
✓ Branch 1 taken 16081416 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 51954 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16133370 if (is_in_scrolling_region() && lensclk && !FFCore.system_suspend[susptLENS])
5377 {
5378 draw_lens_over(dest);
5379 --lensclk;
5380 }
5381
5382 // Draw some text on dest
5383
5384
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 set_clip_rect(dest,0,0,256,232);
5385
5386
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 if(!get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5387
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 draw_msgstr(6);
5388
5389 // Draw the subscreen, without clipping
5390
2/2
✓ Branch 0 taken 6881986 times.
✓ Branch 1 taken 9251384 times.
16133370 if(get_qr(qr_SUBSCREENOVERSPRITES))
5391 {
5392
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 6839730 times.
6881986 if (drawPassiveSubscreenSeparate)
5393
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 blit(dest, framebuf_no_passive_subscreen, 0, 0, 0, 0, dest->w, dest->h);
5394
5395
2/4
✓ Branch 0 taken 6881986 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6881986 times.
✗ Branch 3 not taken.
6881986 put_passive_subscr(dest, 0, 0, game->should_show_time(), sspUP);
5396
5397
1/2
✓ Branch 0 taken 6881986 times.
✗ Branch 1 not taken.
6881986 do_primitives(dest, 7);
5398
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 6839730 times.
6881986 if (drawPassiveSubscreenSeparate)
5399
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 do_primitives(framebuf_no_passive_subscreen, 7);
5400 6881986 }
5401
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9251384 times.
9251384 else if (!classic_draw)
5402 do_primitives(dest, 7);
5403
5404
1/2
✓ Branch 0 taken 16133370 times.
✗ Branch 1 not taken.
16133370 draw_screen_post_passive_subscreen(dest, any_dark);
5405
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 16091114 times.
16133370 if (drawPassiveSubscreenSeparate)
5406
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 draw_screen_post_passive_subscreen(framebuf_no_passive_subscreen, any_dark);
5407
5408
2/2
✓ Branch 0 taken 15631826 times.
✓ Branch 1 taken 31765196 times.
16133370 set_clip_rect(scrollbuf, 0, 0, scrollbuf->w, scrollbuf->h);
5409
3/4
✓ Branch 0 taken 15519799 times.
✓ Branch 1 taken 168023 times.
✓ Branch 2 taken 15519799 times.
✗ Branch 3 not taken.
15631826 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_POST_DRAW);
5410
5411
2/2
✓ Branch 0 taken 1931 times.
✓ Branch 1 taken 15687822 times.
15689753 for(sprite* spr : temp_sprites)
5412
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1931 times.
1931 delete spr;
5413 79218214 }
5414
5415 // TODO: separate setting door data and drawing door
5416 28153 void put_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t type, bool redraw, bool even_walls)
5417 {
5418
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28153 times.
28153 if (type > 8) return;
5419
5420 28153 int32_t d=scr->door_combo_set;
5421
5422
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15611 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12542 times.
28153 switch(type)
5423 {
5424 case dt_wall:
5425 case dt_walk:
5426 if(!even_walls)
5427 break;
5428 [[fallthrough]];
5429 case dt_pass:
5430
3/4
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 11506 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1036 times.
12542 if(!get_qr(qr_REPLACEOPENDOORS) && !even_walls)
5431 1036 break;
5432 [[fallthrough]];
5433 case dt_lock:
5434 case dt_shut:
5435 case dt_boss:
5436 case dt_olck:
5437 case dt_osht:
5438 case dt_obos:
5439 case dt_bomb:
5440
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7259 times.
✓ Branch 2 taken 6784 times.
✓ Branch 3 taken 6362 times.
✓ Branch 4 taken 6712 times.
27117 switch(side)
5441 {
5442 case up:
5443 7259 scr->data[pos] = DoorComboSets[d].doorcombo_u[type][0];
5444 7259 scr->cset[pos] = DoorComboSets[d].doorcset_u[type][0];
5445 7259 scr->sflag[pos] = 0;
5446 7259 scr->data[pos+1] = DoorComboSets[d].doorcombo_u[type][1];
5447 7259 scr->cset[pos+1] = DoorComboSets[d].doorcset_u[type][1];
5448 7259 scr->sflag[pos+1] = 0;
5449 7259 scr->data[pos+16] = DoorComboSets[d].doorcombo_u[type][2];
5450 7259 scr->cset[pos+16] = DoorComboSets[d].doorcset_u[type][2];
5451 7259 scr->sflag[pos+16] = 0;
5452 7259 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_u[type][3];
5453 7259 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_u[type][3];
5454 7259 scr->sflag[pos+16+1] = 0;
5455
5456
2/2
✓ Branch 0 taken 5435 times.
✓ Branch 1 taken 1824 times.
7259 if(redraw)
5457 {
5458 3648 putcombo(dest,(pos&15)<<4,pos&0xF0,
5459 1824 DoorComboSets[d].doorcombo_u[type][0],
5460 1824 DoorComboSets[d].doorcset_u[type][0]);
5461 3648 putcombo(dest,((pos&15)<<4)+16,pos&0xF0,
5462 1824 DoorComboSets[d].doorcombo_u[type][1],
5463 1824 DoorComboSets[d].doorcset_u[type][1]);
5464 1824 }
5465
5466 7259 break;
5467
5468 case down:
5469 6784 scr->data[pos] = DoorComboSets[d].doorcombo_d[type][0];
5470 6784 scr->cset[pos] = DoorComboSets[d].doorcset_d[type][0];
5471 6784 scr->sflag[pos] = 0;
5472 6784 scr->data[pos+1] = DoorComboSets[d].doorcombo_d[type][1];
5473 6784 scr->cset[pos+1] = DoorComboSets[d].doorcset_d[type][1];
5474 6784 scr->sflag[pos+1] = 0;
5475 6784 scr->data[pos+16] = DoorComboSets[d].doorcombo_d[type][2];
5476 6784 scr->cset[pos+16] = DoorComboSets[d].doorcset_d[type][2];
5477 6784 scr->sflag[pos+16] = 0;
5478 6784 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_d[type][3];
5479 6784 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_d[type][3];
5480 6784 scr->sflag[pos+16+1] = 0;
5481
5482
2/2
✓ Branch 0 taken 5463 times.
✓ Branch 1 taken 1321 times.
6784 if(redraw)
5483 {
5484 2642 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5485 1321 DoorComboSets[d].doorcombo_d[type][2],
5486 1321 DoorComboSets[d].doorcset_d[type][2]);
5487 2642 putcombo(dest,((pos&15)<<4)+16,(pos&0xF0)+16,
5488 1321 DoorComboSets[d].doorcombo_d[type][3],
5489 1321 DoorComboSets[d].doorcset_d[type][3]);
5490 1321 }
5491
5492 6784 break;
5493
5494 case left:
5495 6362 scr->data[pos] = DoorComboSets[d].doorcombo_l[type][0];
5496 6362 scr->cset[pos] = DoorComboSets[d].doorcset_l[type][0];
5497 6362 scr->sflag[pos] = 0;
5498 6362 scr->data[pos+1] = DoorComboSets[d].doorcombo_l[type][1];
5499 6362 scr->cset[pos+1] = DoorComboSets[d].doorcset_l[type][1];
5500 6362 scr->sflag[pos+1] = 0;
5501 6362 scr->data[pos+16] = DoorComboSets[d].doorcombo_l[type][2];
5502 6362 scr->cset[pos+16] = DoorComboSets[d].doorcset_l[type][2];
5503 6362 scr->sflag[pos+16] = 0;
5504 6362 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_l[type][3];
5505 6362 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_l[type][3];
5506 6362 scr->sflag[pos+16+1] = 0;
5507 6362 scr->data[pos+32] = DoorComboSets[d].doorcombo_l[type][4];
5508 6362 scr->cset[pos+32] = DoorComboSets[d].doorcset_l[type][4];
5509 6362 scr->sflag[pos+32] = 0;
5510 6362 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_l[type][5];
5511 6362 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_l[type][5];
5512 6362 scr->sflag[pos+32+1] = 0;
5513
5514
2/2
✓ Branch 0 taken 4873 times.
✓ Branch 1 taken 1489 times.
6362 if(redraw)
5515 {
5516 2978 putcombo(dest,(pos&15)<<4,pos&0xF0,
5517 1489 DoorComboSets[d].doorcombo_l[type][0],
5518 1489 DoorComboSets[d].doorcset_l[type][0]);
5519 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5520 1489 DoorComboSets[d].doorcombo_l[type][2],
5521 1489 DoorComboSets[d].doorcset_l[type][2]);
5522 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5523 1489 DoorComboSets[d].doorcombo_l[type][4],
5524 1489 DoorComboSets[d].doorcset_l[type][4]);
5525 1489 }
5526
5527 6362 break;
5528
5529 case right:
5530 6712 scr->data[pos] = DoorComboSets[d].doorcombo_r[type][0];
5531 6712 scr->cset[pos] = DoorComboSets[d].doorcset_r[type][0];
5532 6712 scr->sflag[pos] = 0;
5533 6712 scr->data[pos+1] = DoorComboSets[d].doorcombo_r[type][1];
5534 6712 scr->cset[pos+1] = DoorComboSets[d].doorcset_r[type][1];
5535 6712 scr->sflag[pos+1] = 0;
5536 6712 scr->data[pos+16] = DoorComboSets[d].doorcombo_r[type][2];
5537 6712 scr->cset[pos+16] = DoorComboSets[d].doorcset_r[type][2];
5538 6712 scr->sflag[pos+16] = 0;
5539 6712 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_r[type][3];
5540 6712 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_r[type][3];
5541 6712 scr->sflag[pos+16+1] = 0;
5542 6712 scr->data[pos+32] = DoorComboSets[d].doorcombo_r[type][4];
5543 6712 scr->cset[pos+32] = DoorComboSets[d].doorcset_r[type][4];
5544 6712 scr->sflag[pos+32] = 0;
5545 6712 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_r[type][5];
5546 6712 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_r[type][5];
5547 6712 scr->sflag[pos+32+1] = 0;
5548
5549
2/2
✓ Branch 0 taken 5058 times.
✓ Branch 1 taken 1654 times.
6712 if(redraw)
5550 {
5551 3308 putcombo(dest,(pos&15)<<4,pos&0xF0,
5552 1654 DoorComboSets[d].doorcombo_r[type][0],
5553 1654 DoorComboSets[d].doorcset_r[type][0]);
5554 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5555 1654 DoorComboSets[d].doorcombo_r[type][2],
5556 1654 DoorComboSets[d].doorcset_r[type][2]);
5557 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5558 1654 DoorComboSets[d].doorcombo_r[type][4],
5559 1654 DoorComboSets[d].doorcset_r[type][4]);
5560 1654 }
5561
5562 6712 break;
5563 }
5564
5565 27117 break;
5566
5567 default:
5568 break;
5569 }
5570 28153 }
5571
5572 706556 static void over_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t offx, int32_t offy)
5573 {
5574 706556 int32_t door_combo_set = scr->door_combo_set;
5575 706556 int32_t x = (pos&15)<<4;
5576 706556 int32_t y = (pos&0xF0);
5577 706556 int32_t d = door_combo_set;
5578 706556 x += offx;
5579 706556 y += offy;
5580
5581
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 161136 times.
✓ Branch 2 taken 179643 times.
✓ Branch 3 taken 196353 times.
✓ Branch 4 taken 169424 times.
706556 switch(side)
5582 {
5583 case up:
5584 322272 overcombo2(dest,x,y,
5585 161136 DoorComboSets[d].bombdoorcombo_u[0],
5586 161136 DoorComboSets[d].bombdoorcset_u[0]);
5587 322272 overcombo2(dest,x+16,y,
5588 161136 DoorComboSets[d].bombdoorcombo_u[1],
5589 161136 DoorComboSets[d].bombdoorcset_u[1]);
5590 161136 break;
5591
5592 case down:
5593 359286 overcombo2(dest,x,y,
5594 179643 DoorComboSets[d].bombdoorcombo_d[0],
5595 179643 DoorComboSets[d].bombdoorcset_d[0]);
5596 359286 overcombo2(dest,x+16,y,
5597 179643 DoorComboSets[d].bombdoorcombo_d[1],
5598 179643 DoorComboSets[d].bombdoorcset_d[1]);
5599 179643 break;
5600
5601 case left:
5602 392706 overcombo2(dest,x,y,
5603 196353 DoorComboSets[d].bombdoorcombo_l[0],
5604 196353 DoorComboSets[d].bombdoorcset_l[0]);
5605 392706 overcombo2(dest,x,y+16,
5606 196353 DoorComboSets[d].bombdoorcombo_l[1],
5607 196353 DoorComboSets[d].bombdoorcset_l[1]);
5608 392706 overcombo2(dest,x,y+16,
5609 196353 DoorComboSets[d].bombdoorcombo_l[2],
5610 196353 DoorComboSets[d].bombdoorcset_l[2]);
5611 196353 break;
5612
5613 case right:
5614 338848 overcombo2(dest,x,y,
5615 169424 DoorComboSets[d].bombdoorcombo_r[0],
5616 169424 DoorComboSets[d].bombdoorcset_r[0]);
5617 338848 overcombo2(dest,x,y+16,
5618 169424 DoorComboSets[d].bombdoorcombo_r[1],
5619 169424 DoorComboSets[d].bombdoorcset_r[1]);
5620 338848 overcombo2(dest,x,y+16,
5621 169424 DoorComboSets[d].bombdoorcombo_r[2],
5622 169424 DoorComboSets[d].bombdoorcset_r[2]);
5623 169424 break;
5624 }
5625 706556 }
5626
5627 47568 void update_door(mapscr* scr, int32_t side, int32_t door, bool even_walls)
5628 {
5629
7/8
✓ Branch 0 taken 47460 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 47460 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22925 times.
✓ Branch 5 taken 24535 times.
✓ Branch 6 taken 530 times.
✓ Branch 7 taken 22395 times.
47568 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5630 25173 return;
5631
5632 int32_t doortype;
5633
5634
10/12
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 655 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12492 times.
✓ Branch 5 taken 910 times.
✓ Branch 6 taken 1553 times.
✓ Branch 7 taken 3192 times.
✓ Branch 8 taken 1694 times.
✓ Branch 9 taken 172 times.
✓ Branch 10 taken 67 times.
✓ Branch 11 taken 1138 times.
22395 switch(door)
5635 {
5636 case dWALL:
5637 doortype=dt_wall;
5638 break;
5639
5640 case dWALK:
5641 doortype=dt_walk;
5642 break;
5643
5644 case dOPEN:
5645 12492 doortype=dt_pass;
5646 12492 break;
5647
5648 case dLOCKED:
5649 910 doortype=dt_lock;
5650 910 break;
5651
5652 case dUNLOCKED:
5653 1553 doortype=dt_olck;
5654 1553 break;
5655
5656 case dSHUTTER:
5657
3/4
✓ Branch 0 taken 2783 times.
✓ Branch 1 taken 409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2783 times.
3192 if(screenscrolling && ((HeroDir()^1)==side))
5658 {
5659 doortype=dt_osht;
5660 get_screen_state(scr->screen).open_doors = -4;
5661 break;
5662 }
5663
5664 [[fallthrough]];
5665 case d1WAYSHUTTER:
5666 3714 doortype=dt_shut;
5667 3714 break;
5668
5669 case dOPENSHUTTER:
5670 1694 doortype=dt_osht;
5671 1694 break;
5672
5673 case dBOSS:
5674 172 doortype=dt_boss;
5675 172 break;
5676
5677 case dOPENBOSS:
5678 67 doortype=dt_obos;
5679 67 break;
5680
5681 case dBOMBED:
5682 1138 doortype=dt_bomb;
5683 1138 break;
5684
5685 default:
5686 655 return;
5687 }
5688
5689
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5629 times.
✓ Branch 2 taken 5770 times.
✓ Branch 3 taken 5111 times.
✓ Branch 4 taken 5230 times.
21740 switch(side)
5690 {
5691 case up:
5692 5629 put_door(scr,nullptr,7,side,doortype,false,even_walls);
5693 5629 break;
5694
5695 case down:
5696 5770 put_door(scr,nullptr,151,side,doortype,false,even_walls);
5697 5770 break;
5698
5699 case left:
5700 5111 put_door(scr,nullptr,64,side,doortype,false,even_walls);
5701 5111 break;
5702
5703 case right:
5704 5230 put_door(scr,nullptr,78,side,doortype,false,even_walls);
5705 5230 break;
5706 }
5707 47568 }
5708
5709 6504 void putdoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t door, bool redraw, bool even_walls)
5710 {
5711 /*
5712 #define dWALL 0 // 000 0
5713 #define dBOMB 6 // 011 0
5714 #define 8 // 100 0
5715 enum {dt_pass=0, dt_lock, dt_shut, dt_boss, dt_olck, dt_osht, dt_obos, dt_wall, dt_bomb, dt_walk, dt_max};
5716 */
5717
5718
7/8
✓ Branch 0 taken 6504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6500 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6417 times.
✓ Branch 5 taken 83 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 6409 times.
6504 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5719 91 return;
5720
5721 int32_t doortype;
5722
5723
8/12
✓ Branch 0 taken 227 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 362 times.
✓ Branch 7 taken 1530 times.
✓ Branch 8 taken 3958 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 51 times.
✓ Branch 11 taken 231 times.
6413 switch(door)
5724 {
5725 case dWALL:
5726 doortype=dt_wall;
5727 break;
5728
5729 case dWALK:
5730 doortype=dt_walk;
5731 break;
5732
5733 case dOPEN:
5734 50 doortype=dt_pass;
5735 50 break;
5736
5737 case dLOCKED:
5738 doortype=dt_lock;
5739 break;
5740
5741 case dUNLOCKED:
5742 362 doortype=dt_olck;
5743 362 break;
5744
5745 case dSHUTTER:
5746
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1530 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1530 if(screenscrolling && ((HeroDir()^1)==side))
5747 {
5748 doortype=dt_osht;
5749 get_screen_state(cur_screen).open_doors = -4;
5750 break;
5751 }
5752
5753 [[fallthrough]];
5754 case d1WAYSHUTTER:
5755 1757 doortype=dt_shut;
5756 1757 break;
5757
5758 case dOPENSHUTTER:
5759 3958 doortype=dt_osht;
5760 3958 break;
5761
5762 case dBOSS:
5763 4 doortype=dt_boss;
5764 4 break;
5765
5766 case dOPENBOSS:
5767 51 doortype=dt_obos;
5768 51 break;
5769
5770 case dBOMBED:
5771 231 doortype=dt_bomb;
5772 231 break;
5773
5774 default:
5775 return;
5776 }
5777
5778
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1860 times.
✓ Branch 2 taken 1357 times.
✓ Branch 3 taken 1514 times.
✓ Branch 4 taken 1682 times.
6413 switch(side)
5779 {
5780 case up:
5781
2/2
✓ Branch 0 taken 1791 times.
✓ Branch 1 taken 69 times.
1860 switch(door)
5782 {
5783 case dBOMBED:
5784
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
138 if(redraw)
5785 {
5786 69 over_door(scr,dest,39,side,0,0);
5787 69 }
5788 [[fallthrough]];
5789 default:
5790 1860 put_door(scr,dest,7,side,doortype,redraw, even_walls);
5791 1860 break;
5792 }
5793
5794 1860 break;
5795
5796 case down:
5797
2/2
✓ Branch 0 taken 1318 times.
✓ Branch 1 taken 39 times.
1357 switch(door)
5798 {
5799 case dBOMBED:
5800
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if(redraw)
5801 {
5802 39 over_door(scr,dest,135,side,0,0);
5803 39 }
5804 [[fallthrough]];
5805 default:
5806 1357 put_door(scr,dest,151,side,doortype,redraw, even_walls);
5807 1357 break;
5808 }
5809
5810 1357 break;
5811
5812 case left:
5813
2/2
✓ Branch 0 taken 1463 times.
✓ Branch 1 taken 51 times.
1514 switch(door)
5814 {
5815 case dBOMBED:
5816
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 if(redraw)
5817 {
5818 51 over_door(scr,dest,66,side,0,0);
5819 51 }
5820 [[fallthrough]];
5821 default:
5822 1514 put_door(scr,dest,64,side,doortype,redraw, even_walls);
5823 1514 break;
5824 }
5825
5826 1514 break;
5827
5828 case right:
5829
2/2
✓ Branch 0 taken 1610 times.
✓ Branch 1 taken 72 times.
1682 switch(door)
5830 {
5831 case dBOMBED:
5832
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
144 if(redraw)
5833 {
5834 72 over_door(scr,dest,77,side,0,0);
5835 72 }
5836 [[fallthrough]];
5837 default:
5838 1682 put_door(scr,dest,78,side,doortype,redraw, even_walls);
5839 1682 break;
5840 }
5841
5842 1682 break;
5843 }
5844 6504 }
5845
5846 586 void putcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5847 {
5848
1/2
✓ Branch 0 taken 586 times.
✗ Branch 1 not taken.
586 if(combo!=0)
5849 {
5850 586 putcombo(dest,x, y, combo, cset);
5851 586 }
5852 586 }
5853
5854 293 void overcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5855 {
5856
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 74 times.
293 if(combo!=0)
5857 {
5858 219 overcombo(dest,x, y, combo, cset);
5859 219 }
5860 293 }
5861
5862 125 void showbombeddoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t offx, int32_t offy)
5863 {
5864 125 int32_t d = scr->door_combo_set;
5865
5866
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 37 times.
125 switch(side)
5867 {
5868 case up:
5869 86 putcombo_not_zero(dest,((7&15)<<4) + offx,(7&0xF0) + offy,
5870 43 DoorComboSets[d].doorcombo_u[dt_bomb][0],
5871 43 DoorComboSets[d].doorcset_u[dt_bomb][0]);
5872 86 putcombo_not_zero(dest,((8&15)<<4) + offx,(8&0xF0) + offy,
5873 43 DoorComboSets[d].doorcombo_u[dt_bomb][1],
5874 43 DoorComboSets[d].doorcset_u[dt_bomb][1]);
5875 86 putcombo_not_zero(dest,((23&15)<<4) + offx,(23&0xF0) + offy,
5876 43 DoorComboSets[d].doorcombo_u[dt_bomb][2],
5877 43 DoorComboSets[d].doorcset_u[dt_bomb][2]);
5878 86 putcombo_not_zero(dest,((24&15)<<4) + offx,(24&0xF0) + offy,
5879 43 DoorComboSets[d].doorcombo_u[dt_bomb][3],
5880 43 DoorComboSets[d].doorcset_u[dt_bomb][3]);
5881 86 overcombo_not_zero(dest,((39&15)<<4) + offx,(39&0xF0) + offy,
5882 43 DoorComboSets[d].bombdoorcombo_u[0],
5883 43 DoorComboSets[d].bombdoorcset_u[0]);
5884 86 overcombo_not_zero(dest,((40&15)<<4) + offx,(40&0xF0) + offy,
5885 43 DoorComboSets[d].bombdoorcombo_u[1],
5886 43 DoorComboSets[d].bombdoorcset_u[1]);
5887 43 break;
5888
5889 case down:
5890 78 putcombo_not_zero(dest,((151&15)<<4) + offx,(151&0xF0) + offy,
5891 39 DoorComboSets[d].doorcombo_d[dt_bomb][0],
5892 39 DoorComboSets[d].doorcset_d[dt_bomb][0]);
5893 78 putcombo_not_zero(dest,((152&15)<<4) + offx,(152&0xF0) + offy,
5894 39 DoorComboSets[d].doorcombo_d[dt_bomb][1],
5895 39 DoorComboSets[d].doorcset_d[dt_bomb][1]);
5896 78 putcombo_not_zero(dest,((167&15)<<4) + offx,(167&0xF0) + offy,
5897 39 DoorComboSets[d].doorcombo_d[dt_bomb][2],
5898 39 DoorComboSets[d].doorcset_d[dt_bomb][2]);
5899 78 putcombo_not_zero(dest,((168&15)<<4) + offx,(168&0xF0) + offy,
5900 39 DoorComboSets[d].doorcombo_d[dt_bomb][3],
5901 39 DoorComboSets[d].doorcset_d[dt_bomb][3]);
5902 78 overcombo_not_zero(dest,((135&15)<<4) + offx,(135&0xF0) + offy,
5903 39 DoorComboSets[d].bombdoorcombo_d[0],
5904 39 DoorComboSets[d].bombdoorcset_d[0]);
5905 78 overcombo_not_zero(dest,((136&15)<<4) + offx,(136&0xF0) + offy,
5906 39 DoorComboSets[d].bombdoorcombo_d[1],
5907 39 DoorComboSets[d].bombdoorcset_d[1]);
5908 39 break;
5909
5910 case left:
5911 12 putcombo_not_zero(dest,((64&15)<<4) + offx,(64&0xF0) + offy,
5912 6 DoorComboSets[d].doorcombo_l[dt_bomb][0],
5913 6 DoorComboSets[d].doorcset_l[dt_bomb][0]);
5914 12 putcombo_not_zero(dest,((65&15)<<4) + offx,(65&0xF0) + offy,
5915 6 DoorComboSets[d].doorcombo_l[dt_bomb][1],
5916 6 DoorComboSets[d].doorcset_l[dt_bomb][1]);
5917 12 putcombo_not_zero(dest,((80&15)<<4) + offx,(80&0xF0) + offy,
5918 6 DoorComboSets[d].doorcombo_l[dt_bomb][2],
5919 6 DoorComboSets[d].doorcset_l[dt_bomb][2]);
5920 12 putcombo_not_zero(dest,((81&15)<<4) + offx,(81&0xF0) + offy,
5921 6 DoorComboSets[d].doorcombo_l[dt_bomb][3],
5922 6 DoorComboSets[d].doorcset_l[dt_bomb][3]);
5923 12 putcombo_not_zero(dest,((96&15)<<4) + offx,(96&0xF0) + offy,
5924 6 DoorComboSets[d].doorcombo_l[dt_bomb][4],
5925 6 DoorComboSets[d].doorcset_l[dt_bomb][4]);
5926 12 putcombo_not_zero(dest,((97&15)<<4) + offx,(97&0xF0) + offy,
5927 6 DoorComboSets[d].doorcombo_l[dt_bomb][5],
5928 6 DoorComboSets[d].doorcset_l[dt_bomb][5]);
5929 12 overcombo_not_zero(dest,((66&15)<<4) + offx,(66&0xF0) + offy,
5930 6 DoorComboSets[d].bombdoorcombo_l[0],
5931 6 DoorComboSets[d].bombdoorcset_l[0]);
5932 12 overcombo_not_zero(dest,((82&15)<<4) + offx,(82&0xF0) + offy,
5933 6 DoorComboSets[d].bombdoorcombo_l[1],
5934 6 DoorComboSets[d].bombdoorcset_l[1]);
5935 12 overcombo_not_zero(dest,((98&15)<<4) + offx,(98&0xF0) + offy,
5936 6 DoorComboSets[d].bombdoorcombo_l[2],
5937 6 DoorComboSets[d].bombdoorcset_l[2]);
5938 6 break;
5939
5940 case right:
5941 74 putcombo_not_zero(dest,((78&15)<<4) + offx,(78&0xF0) + offy,
5942 37 DoorComboSets[d].doorcombo_r[dt_bomb][0],
5943 37 DoorComboSets[d].doorcset_r[dt_bomb][0]);
5944 74 putcombo_not_zero(dest,((79&15)<<4) + offx,(79&0xF0) + offy,
5945 37 DoorComboSets[d].doorcombo_r[dt_bomb][1],
5946 37 DoorComboSets[d].doorcset_r[dt_bomb][1]);
5947 74 putcombo_not_zero(dest,((94&15)<<4) + offx,(94&0xF0) + offy,
5948 37 DoorComboSets[d].doorcombo_r[dt_bomb][2],
5949 37 DoorComboSets[d].doorcset_r[dt_bomb][2]);
5950 74 putcombo_not_zero(dest,((95&15)<<4) + offx,(95&0xF0) + offy,
5951 37 DoorComboSets[d].doorcombo_r[dt_bomb][3],
5952 37 DoorComboSets[d].doorcset_r[dt_bomb][3]);
5953 74 putcombo_not_zero(dest,((110&15)<<4) + offx,(110&0xF0) + offy,
5954 37 DoorComboSets[d].doorcombo_r[dt_bomb][4],
5955 37 DoorComboSets[d].doorcset_r[dt_bomb][4]);
5956 74 putcombo_not_zero(dest,((111&15)<<4) + offx,(111&0xF0) + offy,
5957 37 DoorComboSets[d].doorcombo_r[dt_bomb][5],
5958 37 DoorComboSets[d].doorcset_r[dt_bomb][5]);
5959 74 overcombo_not_zero(dest,((77&15)<<4) + offx,(77&0xF0) + offy,
5960 37 DoorComboSets[d].bombdoorcombo_r[0],
5961 37 DoorComboSets[d].bombdoorcset_r[0]);
5962 74 overcombo_not_zero(dest,((93&15)<<4) + offx,(93&0xF0) + offy,
5963 37 DoorComboSets[d].bombdoorcombo_r[1],
5964 37 DoorComboSets[d].bombdoorcset_r[1]);
5965 74 overcombo_not_zero(dest,((109&15)<<4) + offx,(109&0xF0) + offy,
5966 37 DoorComboSets[d].bombdoorcombo_r[2],
5967 37 DoorComboSets[d].bombdoorcset_r[2]);
5968 37 break;
5969 }
5970 125 }
5971
5972 5530036 void openshutters(mapscr* scr)
5973 {
5974 5530036 bool opened_door = false;
5975
2/2
✓ Branch 0 taken 5530036 times.
✓ Branch 1 taken 22120144 times.
27650180 for(int32_t i=0; i<4; i++)
5976
2/2
✓ Branch 0 taken 22116186 times.
✓ Branch 1 taken 3958 times.
22124102 if(scr->door[i]==dSHUTTER)
5977 {
5978 3958 putdoor(scr, scrollbuf, i, dOPENSHUTTER);
5979 3958 scr->door[i]=dOPENSHUTTER;
5980 3958 opened_door = true;
5981 3958 }
5982
5983 5530036 auto& combo_cache = combo_caches::shutter;
5984 2222457862 for_every_combo_in_screen(create_screen_handles(scr), [&](const auto& handle) {
5985
3/4
✓ Branch 0 taken 2215005225 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1922594 times.
✗ Branch 3 not taken.
2216927826 if (!combo_cache.minis[handle.data()].shutter)
5986 2216927819 return;
5987
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
5988 7 return trig.trigger_flags.get(TRIGFLAG_SHUTTER);
5989 });
5990 2216927826 });
5991
5992
2/2
✓ Branch 0 taken 5527305 times.
✓ Branch 1 taken 2731 times.
5530036 if(opened_door)
5993 2731 sfx(WAV_DOOR);
5994 5530036 }
5995
5996 15715450 void clear_darkroom_bitmaps()
5997 {
5998 15715450 clear_to_color(darkscr_bmp, game->get_darkscr_color());
5999 15715450 clear_to_color(darkscr_bmp_trans, game->get_darkscr_color());
6000 15715450 }
6001
6002 16743484 bool is_dark(const mapscr* scr)
6003 {
6004 16743484 bool dark = scr->flags&fDARK;
6005
2/2
✓ Branch 0 taken 3722 times.
✓ Branch 1 taken 16739762 times.
16743484 if (region_is_lit) return !dark;
6006 16739762 return dark;
6007 16743484 }
6008
6009 53189 bool scrolling_is_dark(const mapscr* scr)
6010 {
6011 53189 bool dark = scr->flags&fDARK;
6012
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 53187 times.
53189 if (scrolling_region_is_lit) return !dark;
6013 53187 return dark;
6014 53189 }
6015
6016 38434 bool is_any_dark()
6017 {
6018 38434 bool dark = false;
6019 78124 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
6020 39690 dark |= (bool)(is_dark(scr));
6021 39690 });
6022 38434 return dark;
6023 }
6024
6025
3/4
✓ Branch 0 taken 2989 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2562 times.
✓ Branch 3 taken 427 times.
2989 static mapscr prev_origin_scrs[7];
6026 427 static std::set<int> loadscr_ffc_script_ids_to_remove;
6027
6028 static void handle_screen_overlay(const std::vector<mapscr*>& screens)
6029 {
6030 mapscr* base_scr = screens[0];
6031 mapscr* previous_scr = &prev_origin_scrs[0];
6032
6033 for (int i = 0; i < 176; i++)
6034 {
6035 if (base_scr->data[i] == 0)
6036 {
6037 base_scr->data[i] = previous_scr->data[i];
6038 base_scr->sflag[i] = previous_scr->sflag[i];
6039 base_scr->cset[i] = previous_scr->cset[i];
6040 }
6041 }
6042
6043 for (int i = 0; i < 6; i++)
6044 {
6045 if (previous_scr->layermap[i] > 0 && base_scr->layermap[i] > 0)
6046 {
6047 int lm = (base_scr->layermap[i]-1)*MAPSCRS+base_scr->layerscreen[i];
6048 int fm = (previous_scr->layermap[i]-1)*MAPSCRS+previous_scr->layerscreen[i];
6049
6050 for (int j = 0; j < 176; j++)
6051 {
6052 if (TheMaps[lm].data[j] == 0)
6053 {
6054 TheMaps[lm].data[j] = TheMaps[fm].data[j];
6055 TheMaps[lm].sflag[j] = TheMaps[fm].sflag[j];
6056 TheMaps[lm].cset[j] = TheMaps[fm].cset[j];
6057 }
6058 }
6059 }
6060 }
6061
6062 for (int i = 1; i <= 6; i++)
6063 {
6064 mapscr* scr = screens[i];
6065 previous_scr = &prev_origin_scrs[i];
6066
6067 if (scr->layermap[i] > 0)
6068 {
6069 for (int y = 0; y < 11; y++)
6070 {
6071 for (int x = 0; x < 16; x++)
6072 {
6073 int c = y*16+x;
6074
6075 if (scr->data[c]==0)
6076 {
6077 scr->data[c] = previous_scr->data[c];
6078 scr->sflag[c] = previous_scr->sflag[c];
6079 scr->cset[c] = previous_scr->cset[c];
6080 }
6081 }
6082 }
6083 }
6084 }
6085 }
6086
6087 38774 static void load_a_screen_and_layers_init(int dmap, int screen, int ldir, bool screen_overlay, bool ffc_overlay)
6088 {
6089 38774 std::vector<mapscr*> screens;
6090
6091
1/2
✓ Branch 0 taken 38774 times.
✗ Branch 1 not taken.
38774 const mapscr* source = get_canonical_scr(cur_map, screen);
6092
2/4
✓ Branch 0 taken 38774 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38774 times.
✗ Branch 3 not taken.
38774 mapscr* base_scr = new mapscr(*source);
6093 38774 temporary_screens[screen*7] = base_scr;
6094
1/2
✓ Branch 0 taken 38774 times.
✗ Branch 1 not taken.
38774 screens.push_back(base_scr);
6095
6096 38774 base_scr->valid |= mVALID; // layer 0 is always valid
6097
6098
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 37530 times.
38774 if (screen == cur_screen)
6099 37530 origin_scr = base_scr;
6100
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 37530 times.
38774 if (screen == Hero.current_screen)
6101 37530 hero_scr = prev_hero_scr = base_scr;
6102
6103
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 38630 times.
38774 if (source->script > 0)
6104
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6105
6106
2/2
✓ Branch 0 taken 38774 times.
✓ Branch 1 taken 232644 times.
271418 for (int i = 0; i < 6; i++)
6107 {
6108
2/2
✓ Branch 0 taken 176175 times.
✓ Branch 1 taken 56469 times.
232644 if(source->layermap[i]>0)
6109 {
6110
3/6
✓ Branch 0 taken 56469 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56469 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 56469 times.
✗ Branch 5 not taken.
56469 mapscr* layer_scr = new mapscr(*get_canonical_scr(source->layermap[i]-1, source->layerscreen[i]));
6111 56469 layer_scr->map = cur_map;
6112 56469 layer_scr->screen = screen;
6113 56469 layer_scr->valid |= mVALID;
6114
1/2
✓ Branch 0 taken 56469 times.
✗ Branch 1 not taken.
56469 screens.push_back(layer_scr);
6115 56469 }
6116 else
6117 {
6118
2/4
✓ Branch 0 taken 176175 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 176175 times.
✗ Branch 3 not taken.
176175 mapscr* layer_scr = new mapscr();
6119 176175 layer_scr->map = cur_map;
6120 176175 layer_scr->screen = screen;
6121
1/2
✓ Branch 0 taken 176175 times.
✗ Branch 1 not taken.
176175 screens.push_back(layer_scr);
6122 }
6123 232644 temporary_screens[screen*7+i+1] = screens[i+1];
6124 232644 }
6125
6126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38774 times.
38774 if (screen_overlay)
6127 handle_screen_overlay(screens);
6128
6129
2/2
✓ Branch 0 taken 145 times.
✓ Branch 1 taken 38629 times.
38774 if (ffc_overlay)
6130 {
6131 145 mapscr* previous_scr = &prev_origin_scrs[0];
6132
1/2
✓ Branch 0 taken 145 times.
✗ Branch 1 not taken.
145 int num_ffcs = previous_scr->numFFC();
6133
2/2
✓ Branch 0 taken 4640 times.
✓ Branch 1 taken 145 times.
4785 for (int i = 0; i < num_ffcs; i++)
6134 {
6135
2/2
✓ Branch 0 taken 4365 times.
✓ Branch 1 taken 275 times.
4640 if ((previous_scr->ffcs[i].flags&ffc_carryover))
6136 {
6137
2/4
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 275 times.
✗ Branch 3 not taken.
275 auto& ffc = base_scr->getFFC(i) = previous_scr->ffcs[i];
6138 275 ffc.screen_spawned = screen;
6139
6140
1/2
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
275 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + i;
6141
1/2
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
275 loadscr_ffc_script_ids_to_remove.erase(ffc_id);
6142
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 275 times.
275 if (previous_scr->ffcs[i].flags&ffc_scriptreset)
6143 {
6144 FFCore.reset_script_engine_data(ScriptType::FFC, ffc_id);
6145 }
6146 275 }
6147 4640 }
6148 145 }
6149
6150
1/2
✓ Branch 0 taken 38774 times.
✗ Branch 1 not taken.
1145565 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6151
1/2
✓ Branch 0 taken 38774 times.
✗ Branch 1 not taken.
38774 int num_ffcs = base_scr->numFFC();
6152
2/2
✓ Branch 0 taken 1106791 times.
✓ Branch 1 taken 38774 times.
1145565 for (word i = 0; i < num_ffcs; i++)
6153 {
6154 1106791 base_scr->ffcs[i].screen_spawned = screen;
6155
1/2
✓ Branch 0 taken 1106791 times.
✗ Branch 1 not taken.
1106791 base_scr->ffcs[i].x += offx;
6156
1/2
✓ Branch 0 taken 1106791 times.
✗ Branch 1 not taken.
1106791 base_scr->ffcs[i].y += offy;
6157 1106791 }
6158 38774 }
6159
6160 38774 static void load_a_screen_and_layers_post(int dmap, int screen, int ldir)
6161 {
6162 38774 mapscr* base_scr = get_scr(screen);
6163 38774 int mi = mapind(cur_map, screen);
6164
6165 // Apply perm secrets, if applicable.
6166
2/2
✓ Branch 0 taken 11520 times.
✓ Branch 1 taken 27254 times.
38774 if (canPermSecret(dmap, screen))
6167 {
6168
2/2
✓ Branch 0 taken 24348 times.
✓ Branch 1 taken 2906 times.
27254 if(game->maps[mi] & mSECRET) // if special stuff done before
6169 {
6170 2906 reveal_hidden_stairs(base_scr, screen, false);
6171 2906 trigger_secrets_for_screen(TriggerSource::SecretsScreenState, base_scr, false);
6172 2906 }
6173
2/2
✓ Branch 0 taken 27251 times.
✓ Branch 1 taken 3 times.
27254 if(game->maps[mi] & mLIGHTBEAM) // if special stuff done before
6174 {
6175
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (int layer = 0; layer <= 6; layer++)
6176 {
6177 21 mapscr* layer_scr = get_scr_layer(screen, layer);
6178
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 21 times.
3717 for (int pos = 0; pos < 176; pos++)
6179 {
6180 3696 newcombo const* cmb = &combobuf[layer_scr->data[pos]];
6181
2/2
✓ Branch 0 taken 3693 times.
✓ Branch 1 taken 3 times.
3696 if(cmb->type == cLIGHTTARGET)
6182 {
6183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(cmb->usrflags&cflag1)) //Unlit version
6184 {
6185 3 layer_scr->data[pos] += 1;
6186 3 }
6187 3 }
6188 3696 }
6189 21 }
6190 3 }
6191 27254 }
6192
6193 38774 auto screen_handles = create_screen_handles(base_scr);
6194
6195 38774 int destlvl = DMaps[dmap].level;
6196 38774 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6197 38774 toggle_gswitches_load(screen_handles);
6198
6199 38774 bool should_check_for_state_things = (screen < 0x80);
6200
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 37867 times.
38774 if (should_check_for_state_things)
6201 {
6202
2/2
✓ Branch 0 taken 37433 times.
✓ Branch 1 taken 434 times.
37867 if (game->maps[mi]&mLOCKBLOCK)
6203 434 remove_lockblocks(screen_handles);
6204
2/2
✓ Branch 0 taken 37778 times.
✓ Branch 1 taken 89 times.
37867 if (game->maps[mi]&mBOSSLOCKBLOCK)
6205 89 remove_bosslockblocks(screen_handles);
6206
2/2
✓ Branch 0 taken 37699 times.
✓ Branch 1 taken 168 times.
37867 if (game->maps[mi]&mCHEST)
6207 168 remove_chests(screen_handles);
6208
1/2
✓ Branch 0 taken 37867 times.
✗ Branch 1 not taken.
37867 if (game->maps[mi]&mLOCKEDCHEST)
6209 remove_lockedchests(screen_handles);
6210
2/2
✓ Branch 0 taken 37856 times.
✓ Branch 1 taken 11 times.
37867 if (game->maps[mi]&mBOSSCHEST)
6211 11 remove_bosschests(screen_handles);
6212
6213 37867 clear_xdoors_mi(screen_handles, mi, true);
6214 37867 clear_xstatecombos_mi(screen_handles, mi, true);
6215 37867 }
6216
6217 // check doors
6218
2/2
✓ Branch 0 taken 27253 times.
✓ Branch 1 taken 11521 times.
38774 if (isdungeon(dmap, screen))
6219 {
6220
2/2
✓ Branch 0 taken 46084 times.
✓ Branch 1 taken 11521 times.
57605 for(int32_t i=0; i<4; i++)
6221 {
6222 46084 int32_t door=base_scr->door[i];
6223
6224
5/5
✓ Branch 0 taken 5303 times.
✓ Branch 1 taken 36475 times.
✓ Branch 2 taken 2372 times.
✓ Branch 3 taken 230 times.
✓ Branch 4 taken 1704 times.
46084 switch(door)
6225 {
6226 case d1WAYSHUTTER:
6227 case dSHUTTER:
6228
3/4
✓ Branch 0 taken 1694 times.
✓ Branch 1 taken 3609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1694 times.
5303 if ((ldir^1)==i && screen == Hero.current_screen)
6229 {
6230 1694 base_scr->door[i]=dOPENSHUTTER;
6231 1694 }
6232
6233 5303 get_screen_state(screen).open_doors = -4;
6234 5303 break;
6235
6236 case dLOCKED:
6237
3/4
✓ Branch 0 taken 2372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1473 times.
✓ Branch 3 taken 899 times.
2372 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6238 {
6239 1473 base_scr->door[i]=dUNLOCKED;
6240 1473 }
6241
6242 2372 break;
6243
6244 case dBOSS:
6245
3/4
✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 168 times.
230 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6246 {
6247 62 base_scr->door[i]=dOPENBOSS;
6248 62 }
6249
6250 230 break;
6251
6252 case dBOMB:
6253
3/4
✓ Branch 0 taken 1704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1087 times.
✓ Branch 3 taken 617 times.
1704 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6254 {
6255 1087 base_scr->door[i]=dBOMBED;
6256 1087 }
6257
6258 1704 break;
6259 }
6260
6261 46084 update_door(base_scr, i, base_scr->door[i]);
6262
6263
4/4
✓ Branch 0 taken 41517 times.
✓ Branch 1 taken 4567 times.
✓ Branch 2 taken 736 times.
✓ Branch 3 taken 40781 times.
46084 if(door==dSHUTTER||door==d1WAYSHUTTER)
6264 {
6265 5303 base_scr->door[i]=door;
6266 5303 }
6267 46084 }
6268 11521 }
6269
6270
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 38635 times.
38774 if (!(base_scr->flags3 & fCYCLEONINIT))
6271 38635 return;
6272
6273
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 973 times.
1112 for (int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6274 {
6275
4/4
✓ Branch 0 taken 834 times.
✓ Branch 1 taken 139 times.
✓ Branch 2 taken 383 times.
✓ Branch 3 taken 451 times.
973 if (j<0 || base_scr->layermap[j] > 0)
6276 {
6277 522 mapscr* layer_scr = get_scr_layer(screen, j + 1);
6278
3/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 139 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 383 times.
522 mapscr* layerscreen= (j<0 ? base_scr : layer_scr->valid ? layer_scr :
6279 &TheMaps[(base_scr->layermap[j]-1)*MAPSCRS]+base_scr->layerscreen[j]);
6280
6281
2/2
✓ Branch 0 taken 91872 times.
✓ Branch 1 taken 522 times.
92394 for(int32_t i=0; i<176; ++i)
6282 {
6283 91872 int32_t c=layerscreen->data[i];
6284
6285 // New screen flag: Cycle Combos At Screen Init
6286
5/6
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 91807 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
91872 if(combobuf[c].nextcombo != 0 && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6287 {
6288 65 int32_t r = 0;
6289
6290
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 65 times.
149 while(combobuf[c].can_cycle() && r++ < 10)
6291 {
6292 84 newcombo const& cmb = combobuf[c];
6293 84 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6294
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6295 84 layerscreen->data[i] = cid;
6296
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 69 times.
84 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6297
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6298 84 c = layerscreen->data[i];
6299 }
6300 65 }
6301 91872 }
6302 522 }
6303 973 }
6304 38774 }
6305
6306 // Set `cur_screen` to `screen` and load new screens into temporary memory.
6307 //
6308 // Called anytime a player moves to a new screen (either via warping, scrolling, continue, starting
6309 // the game, etc...)
6310 //
6311 // Note: for regions, only the initial screen load calls this function. Simply walking between
6312 // screens in the same region does not use this, because every screen in a region is loaded into
6313 // temporary memory up front.
6314 //
6315 // If scr >= 0x80, `Hero.current_screen` will be saved to `home_screen` and also be loaded into
6316 // `special_warp_return_scr`.
6317 //
6318 // If origin_screen_overlay is true, the old origin_scr combos will be copied to the new origin_scr combos
6319 // on all layers (but only where the new screen has a 0 combo).
6320 //
6321 // TODO: loadscr should set curdmap, but currently callers do that.
6322 37530 void loadscr(int32_t destdmap, int32_t screen, int32_t ldir, bool origin_screen_overlay, bool no_x80_dir)
6323 {
6324 37530 zapp_reporting_set_tag("screen", screen);
6325
2/2
✓ Branch 0 taken 9310 times.
✓ Branch 1 taken 28220 times.
37530 if (destdmap != -1)
6326 9310 zapp_reporting_set_tag("dmap", destdmap);
6327
6328 37530 int32_t orig_destdmap = destdmap;
6329
2/2
✓ Branch 0 taken 9310 times.
✓ Branch 1 taken 28220 times.
37530 if (destdmap < 0) destdmap = cur_dmap;
6330
6331
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37530 times.
37530 if (replay_is_active())
6332 {
6333
2/2
✓ Branch 0 taken 28220 times.
✓ Branch 1 taken 9310 times.
37530 if (orig_destdmap != -1)
6334 {
6335
2/2
✓ Branch 0 taken 8239 times.
✓ Branch 1 taken 1071 times.
9310 if (strlen(DMaps[orig_destdmap].name) > 0)
6336 {
6337
1/2
✓ Branch 0 taken 8239 times.
✗ Branch 1 not taken.
8239 replay_step_comment(fmt::format("dmap={} {}", orig_destdmap, DMaps[orig_destdmap].name));
6338 8239 }
6339 else
6340 {
6341
1/2
✓ Branch 0 taken 1071 times.
✗ Branch 1 not taken.
1071 replay_step_comment(fmt::format("dmap={}", orig_destdmap));
6342 }
6343 9310 }
6344 37530 replay_step_comment_loadscr(screen);
6345
6346 // Reset the rngs and frame count so that recording steps can be modified without impacting
6347 // behavior of later screens.
6348 37530 replay_sync_rng();
6349 37530 }
6350
6351
2/2
✓ Branch 0 taken 1754087 times.
✓ Branch 1 taken 37530 times.
1791617 for (auto& state : get_screen_states())
6352 1754087 state.second.triggered_secrets = false;
6353 37530 slopes.clear();
6354 37530 Hero.clear_platform_ffc();
6355 37530 timeExitAllGenscript(GENSCR_ST_CHANGE_SCREEN);
6356 37530 clear_darkroom_bitmaps();
6357 37530 msgscr = nullptr;
6358
6359
2/2
✓ Branch 0 taken 52507984 times.
✓ Branch 1 taken 37530 times.
52545514 for (word x=0; x<animated_combos; x++)
6360 {
6361
2/2
✓ Branch 0 taken 21102328 times.
✓ Branch 1 taken 31405656 times.
52507984 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6362 {
6363 21102328 combobuf[animated_combo_table4[x][0]].aclk = 0;
6364 21102328 }
6365 52507984 }
6366 37530 reset_combo_animations2();
6367 37530 region_is_lit = false;
6368
6369 // Legacy features (combo and ffc overlays) may need the previous origin screens during loading
6370 // of the new ones.
6371 37530 bool origin_ffc_overlay = false;
6372
2/2
✓ Branch 0 taken 1170 times.
✓ Branch 1 taken 36360 times.
37530 if (origin_scr)
6373 {
6374
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 36358 times.
36360 if (!(origin_scr->flags5&fNOFFCARRYOVER))
6375 {
6376 36358 int c = origin_scr->numFFC();
6377
2/2
✓ Branch 0 taken 36213 times.
✓ Branch 1 taken 1040673 times.
1076886 for (int i = 0; i < c; i++)
6378 {
6379
2/2
✓ Branch 0 taken 1040528 times.
✓ Branch 1 taken 145 times.
1040673 if (origin_scr->ffcs[i].flags&ffc_carryover)
6380 {
6381 145 origin_ffc_overlay = true;
6382 145 break;
6383 }
6384 1040528 }
6385 36358 }
6386
6387
3/4
✓ Branch 0 taken 36360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 145 times.
✓ Branch 3 taken 36215 times.
36360 if (origin_screen_overlay || origin_ffc_overlay)
6388 {
6389
2/2
✓ Branch 0 taken 1015 times.
✓ Branch 1 taken 145 times.
1160 for (int i = 0; i <= 6; i++)
6390 {
6391 1015 mapscr* prev_scr = get_scr_layer(cur_screen, i);
6392
1/2
✓ Branch 0 taken 1015 times.
✗ Branch 1 not taken.
1015 if (prev_scr)
6393 1015 prev_origin_scrs[i] = *prev_scr;
6394 else
6395 prev_origin_scrs[i] = {};
6396 1015 }
6397 145 }
6398 36360 }
6399
6400 // When loading a new screen, all previous FFC scripts end, with one exception.
6401 // Based on origin_ffc_overlay, some ffc scripts don't get reset. This set starts with all of
6402 // them, but scripts that need their data to persist will be removed.
6403 37530 loadscr_ffc_script_ids_to_remove.clear();
6404
2/2
✓ Branch 0 taken 83199388 times.
✓ Branch 1 taken 37530 times.
83236918 for (auto& key : scriptEngineDatas | std::views::keys)
6405 {
6406
2/2
✓ Branch 0 taken 82068435 times.
✓ Branch 1 taken 1130953 times.
83199388 if (key.first == ScriptType::FFC)
6407 1130953 loadscr_ffc_script_ids_to_remove.insert(key.second);
6408 }
6409
6410 37530 load_region(destdmap, screen);
6411
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 36623 times.
37530 home_screen = screen >= 0x80 ? Hero.current_screen : cur_screen;
6412 37530 Hero.current_screen = screen;
6413
6414 37530 cpos_clear_all();
6415 37530 FFCore.destroyScriptableObjectsOfType(ScriptType::Screen);
6416 37530 FFCore.clear_combo_scripts();
6417
6418
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 37366 times.
37530 if (is_in_scrolling_region())
6419 {
6420
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6421 {
6422
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6423 {
6424
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool screen_overlay = origin_screen_overlay && screen == cur_screen;
6425
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool ffc_overlay = origin_ffc_overlay && screen == cur_screen;
6426 1408 load_a_screen_and_layers_init(destdmap, screen, ldir, screen_overlay, ffc_overlay);
6427 1408 }
6428 20992 }
6429 164 }
6430 else
6431 {
6432 37366 load_a_screen_and_layers_init(destdmap, screen, ldir, origin_screen_overlay, origin_ffc_overlay);
6433 }
6434
6435 37530 prepare_current_region_handles();
6436
6437
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 37366 times.
37530 if (is_in_scrolling_region())
6438 {
6439
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6440 {
6441
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6442 {
6443 1408 load_a_screen_and_layers_post(destdmap, screen, ldir);
6444 1408 }
6445 20992 }
6446 164 }
6447 else
6448 {
6449 37366 load_a_screen_and_layers_post(destdmap, screen, ldir);
6450 }
6451
6452 // If on a special screen, load the screen the player is currently on (home_screen) into special_warp_return_scr.
6453
2/2
✓ Branch 0 taken 36623 times.
✓ Branch 1 taken 907 times.
37530 if (screen >= 0x80)
6454
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 431 times.
907 loadscr_old(orig_destdmap, home_screen, no_x80_dir ? -1 : ldir, origin_screen_overlay);
6455
6456 37530 update_slope_comboposes();
6457 37530 cpos_force_update();
6458 37530 trig_trigger_groups();
6459
6460
2/2
✓ Branch 0 taken 1130678 times.
✓ Branch 1 taken 37530 times.
1168208 for (int index : loadscr_ffc_script_ids_to_remove)
6461 {
6462 // Note: ideally would use "destroySprite", but during scrolling the previous
6463 // screen's FFCs are still accessible (even though only the new screen's FFC scripts run).
6464 // The only difference is a call to "release_sprite_owned_objects". To defer FFC script
6465 // owned objects being released until the end of the scroll, here "destroyScriptableObject"
6466 // is used instead.
6467 //
6468 // So when is "release_sprite_owned_objects" called for FFCs? For scrolling screen
6469 // transitions, it's at the end of "scrollscr" via "delete_temporary_screens". Otherwise,
6470 // it is called above when "load_region" calls "clear_temporary_screens".
6471 1130678 FFCore.destroyScriptableObject(ScriptType::FFC, index);
6472 }
6473
6474 // "extended height mode" includes the top 56 pixels as part of the visible mapscr viewport,
6475 // allowing for regions to display 4 more rows of combos (as many as ALTTP does). This part of
6476 // screen is normally reserved for the passive subscreen, but in this mode mapscr combos are drawn below it.
6477 // It is up to the quest designer to make their subscreen be actually transparent.
6478 //
6479 // When not in "extended height mode" (otherwise 56 is 0):
6480 // - playing_field_offset: 56, but changes during earthquakes
6481 // - original_playing_field_offset: always 56
6482 //
6483 // These values are used to adjust where things are drawn on screen to account for the passive subscreen. Examples:
6484 // - yofs of sprites
6485 // - bitmap y offsets in draw_screen
6486 // - drawing offsets for putscr, do_layer
6487 // - drawing offsets for various calls to overtile16 (see bomb weapon explosion)
6488 // - lots more
6489 //
6490 // TODO: consider refactor of yofs, make yofs start as 0 by default and add playing_field_offset at draw time?
6491
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 37388 times.
37530 if (is_extended_height_mode())
6492 {
6493 142 playing_field_offset = 0;
6494 142 original_playing_field_offset = 0;
6495 // A few sprites exist as globals, so we must manually reset them.
6496 142 Hero.yofs = 0;
6497 142 mblock2.yofs = 0;
6498 142 }
6499 else
6500 {
6501 37388 mblock2.yofs = Hero.yofs = playing_field_offset = 56;
6502 37388 original_playing_field_offset = 56;
6503 }
6504 37530 is_any_room_dark = is_any_dark();
6505
6506 37530 game->load_portal();
6507 37530 throwGenScriptEvent(GENSCR_EVENT_CHANGE_SCREEN);
6508
3/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 37495 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
37530 if (Hero.lift_wpn && get_qr(qr_CARRYABLE_NO_ACROSS_SCREEN))
6509 {
6510 delete Hero.lift_wpn;
6511 Hero.lift_wpn = nullptr;
6512 }
6513
6514 37530 enemy_spawning_has_checked_been_here = false;
6515 37530 markBmap(-1, Hero.current_screen);
6516 37530 Hero.maybe_begin_advanced_maze();
6517 37530 }
6518
6519 // Don't use this directly! Use `loadscr` instead.
6520 907 void loadscr_old(int32_t destdmap, int32_t screen,int32_t ldir,bool overlay)
6521 {
6522
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int32_t destlvl = DMaps[destdmap < 0 ? cur_dmap : destdmap].level;
6523
6524 907 mapscr previous_scr = *special_warp_return_scr;
6525 907 mapscr* scr = special_warp_return_scr;
6526
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 const mapscr* source = get_canonical_scr(cur_map, screen);
6527
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 *scr = *source;
6528
6529
2/2
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 907 times.
6349 for (int i = 1; i <= 6; i++)
6530 {
6531
2/2
✓ Branch 0 taken 5059 times.
✓ Branch 1 taken 383 times.
5442 if (scr->layermap[i-1] > 0)
6532
2/4
✓ Branch 0 taken 383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
383 special_warp_return_scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6533 else
6534
2/4
✓ Branch 0 taken 5059 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5059 times.
✗ Branch 3 not taken.
5059 special_warp_return_scrs[i] = {};
6535 5442 }
6536
6537 907 scr->valid |= mVALID; //layer 0 is always valid
6538
6539
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 907 times.
907 if ( source->script > 0 )
6540 {
6541 scr->script = source->script;
6542 for ( int32_t q = 0; q < 8; q++ )
6543 {
6544 scr->screeninitd[q] = source->screeninitd[q];
6545 }
6546 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6547 }
6548 else
6549 {
6550 907 scr->script = 0;
6551 }
6552
6553
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 if(overlay)
6554 {
6555 for(int32_t c=0; c< 176; ++c)
6556 {
6557 if(scr->data[c]==0)
6558 {
6559 scr->data[c]=previous_scr.data[c];
6560 scr->sflag[c]=previous_scr.sflag[c];
6561 scr->cset[c]=previous_scr.cset[c];
6562 }
6563 }
6564
6565 for(int32_t i=0; i<6; i++)
6566 {
6567 if(previous_scr.layermap[i]>0 && scr->layermap[i]>0)
6568 {
6569 int32_t lm = (scr->layermap[i]-1)*MAPSCRS+scr->layerscreen[i];
6570 int32_t fm = (previous_scr.layermap[i]-1)*MAPSCRS+previous_scr.layerscreen[i];
6571
6572 for(int32_t c=0; c< 176; ++c)
6573 {
6574 if(TheMaps[lm].data[c]==0)
6575 {
6576 TheMaps[lm].data[c] = TheMaps[fm].data[c];
6577 TheMaps[lm].sflag[c] = TheMaps[fm].sflag[c];
6578 TheMaps[lm].cset[c] = TheMaps[fm].cset[c];
6579 }
6580 }
6581 }
6582 }
6583 }
6584
6585
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
29900 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6586
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int c = scr->numFFC();
6587
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 28993 times.
29900 for (word i = 0; i < c; i++)
6588 {
6589 28993 scr->ffcs[i].screen_spawned = screen;
6590
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].x += offx;
6591
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].y += offy;
6592 28993 }
6593
6594 907 int mi = mapind(cur_map, screen);
6595
6596 // Apply perm secrets, if applicable.
6597
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if(canPermSecret(destdmap,screen))
6598 {
6599
3/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 332 times.
536 if(game->maps[mi]&mSECRET) // if special stuff done before
6600 {
6601
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 reveal_hidden_stairs(scr, screen, false);
6602
6603
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
6604
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 get_screen_state(special_warp_return_scr->screen).triggered_secrets = true;
6605 204 bool do_replay_comment = true;
6606 204 bool from_active_screen = false;
6607
2/4
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✗ Branch 3 not taken.
204 trigger_secrets_for_screen_internal(create_screen_handles(special_warp_return_scr), from_active_screen, false, -1, do_replay_comment);
6608 204 }
6609
2/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✗ Branch 3 not taken.
536 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6610 {
6611 for (int layer = 0; layer <= 6; layer++)
6612 {
6613 mapscr* tscr = &special_warp_return_scrs[layer];
6614 for (int pos = 0; pos < 176; pos++)
6615 {
6616 newcombo const* cmb = &combobuf[tscr->data[pos]];
6617 if(cmb->type == cLIGHTTARGET)
6618 {
6619 if(!(cmb->usrflags&cflag1)) //Unlit version
6620 {
6621 tscr->data[pos] += 1;
6622 }
6623 }
6624 }
6625 }
6626 }
6627 536 }
6628
6629 screen_handles_t screen_handles;
6630
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 6349 times.
7256 for (int i = 0; i <= 6; i++)
6631
3/4
✓ Branch 0 taken 6349 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1284 times.
✓ Branch 3 taken 5065 times.
6349 screen_handles[i] = {scr, special_warp_return_scrs[i].is_valid() ? &special_warp_return_scrs[i] : nullptr, screen, i};
6632
6633
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 907 times.
✗ Branch 3 not taken.
907 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6634
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 toggle_gswitches_load(screen_handles);
6635
6636
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 902 times.
907 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6637 {
6638
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 remove_lockblocks(screen_handles);
6639 5 }
6640
6641
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 906 times.
907 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6642 {
6643
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6644 1 }
6645
6646
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mCHEST) // if special stuff done before
6647 {
6648 remove_chests(screen_handles);
6649 }
6650
6651
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6652 {
6653 remove_lockedchests(screen_handles);
6654 }
6655
6656
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6657 {
6658 remove_bosschests(screen_handles);
6659 }
6660
6661
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xdoors(screen_handles, true);
6662
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xstatecombos(screen_handles, true);
6663
6664 // check doors
6665
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if (isdungeon(destdmap, screen))
6666 {
6667
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 371 times.
1855 for(int32_t i=0; i<4; i++)
6668 {
6669 1484 int32_t door=scr->door[i];
6670
6671
4/5
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 89 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1295 times.
1484 switch(door)
6672 {
6673 case d1WAYSHUTTER:
6674 case dSHUTTER:
6675 if ((ldir^1)==i && screen == home_screen)
6676 {
6677 scr->door[i]=dOPENSHUTTER;
6678 }
6679
6680 get_screen_state(screen).open_doors = -4;
6681 105 break;
6682
6683 case dLOCKED:
6684
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 80 times.
91 if(game->maps[mi]&(mDOOR_UP<<i))
6685 {
6686 80 scr->door[i]=dUNLOCKED;
6687 80 }
6688
6689 91 break;
6690
6691 case dBOSS:
6692
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 5 times.
9 if(game->maps[mi]&(mDOOR_UP<<i))
6693 {
6694 5 scr->door[i]=dOPENBOSS;
6695 5 }
6696
6697 9 break;
6698
6699 case dBOMB:
6700
3/4
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 51 times.
89 if(game->maps[mi]&(mDOOR_UP<<i))
6701 {
6702 51 scr->door[i]=dBOMBED;
6703 51 }
6704
6705 89 break;
6706 }
6707
6708
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 105 times.
1589 update_door(scr, i, scr->door[i]);
6709
6710
4/4
✓ Branch 0 taken 1390 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1379 times.
1484 if(door==dSHUTTER||door==d1WAYSHUTTER)
6711 {
6712 105 scr->door[i]=door;
6713 105 }
6714 1484 }
6715 371 }
6716
6717
2/2
✓ Branch 0 taken 6139 times.
✓ Branch 1 taken 1117 times.
7256 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6718 {
6719
4/4
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 697 times.
✓ Branch 2 taken 593 times.
✓ Branch 3 taken 4849 times.
6139 if (j<0 || scr->layermap[j] > 0)
6720 {
6721
4/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 907 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 1 times.
1290 mapscr *layerscreen= (j<0 ? scr : special_warp_return_scrs[j+1].valid ? &special_warp_return_scrs[j+1] :
6722 1 &TheMaps[(scr->layermap[j]-1)*MAPSCRS]+scr->layerscreen[j]);
6723
6724
2/2
✓ Branch 0 taken 226830 times.
✓ Branch 1 taken 1500 times.
228330 for(int32_t i=0; i<176; ++i)
6725 {
6726 226830 int32_t c=layerscreen->data[i];
6727
6728 // New screen flag: Cycle Combos At Screen Init
6729
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 226824 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 210 times.
✓ Branch 7 taken 210 times.
226830 if(combobuf[c].nextcombo != 0 && (scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6730 {
6731 210 int32_t r = 0;
6732
6733
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 210 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
210 while(combobuf[c].can_cycle() && r++ < 10)
6734 {
6735 newcombo const& cmb = combobuf[c];
6736 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6737 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6738 layerscreen->data[i] = cid;
6739 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6740 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6741 c = layerscreen->data[i];
6742 }
6743 }
6744 227040 }
6745 1500 }
6746 6349 }
6747 1537 }
6748
6749 // Load screen (and layers). Unlike loadscr, this doesn't load to the global temporary_screens, but
6750 // instead returns an array of mapscr.
6751 // Used to draw/save the map.
6752 47360 std::array<mapscr, 7> loadscr2(int32_t screen)
6753 {
6754 47360 std::array<mapscr, 7> scrs;
6755 47360 mapscr* scr = &scrs[0];
6756
6757
2/2
✓ Branch 0 taken 66834661 times.
✓ Branch 1 taken 47360 times.
66882021 for(word x=0; x<animated_combos; x++)
6758 {
6759
2/2
✓ Branch 0 taken 33899045 times.
✓ Branch 1 taken 32935616 times.
66834661 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6760 {
6761 32935616 combobuf[animated_combo_table4[x][0]].aclk=0;
6762 32935616 }
6763 66834661 }
6764
6765
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 const mapscr* source = get_canonical_scr(cur_map, screen);
6766
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if (!source->is_valid())
6767 {
6768 scrs[0].valid = 0;
6769 return scrs;
6770 }
6771
6772
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 *scr = *get_canonical_scr(cur_map, screen);
6773
2/2
✓ Branch 0 taken 284160 times.
✓ Branch 1 taken 47360 times.
331520 for (int i = 1; i <= 6; i++)
6774 {
6775
2/2
✓ Branch 0 taken 209501 times.
✓ Branch 1 taken 74659 times.
284160 if (scr->layermap[i-1] > 0)
6776
2/4
✓ Branch 0 taken 74659 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 74659 times.
✗ Branch 3 not taken.
74659 scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6777 else
6778
2/4
✓ Branch 0 taken 209501 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 209501 times.
✗ Branch 3 not taken.
209501 scrs[i] = {};
6779 284160 }
6780
6781 screen_handles_t screen_handles;
6782
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 331520 times.
378880 for (int i = 0; i < 7; i++)
6783
3/4
✓ Branch 0 taken 331520 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114582 times.
✓ Branch 3 taken 216938 times.
331520 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
6784
6785 47360 int mi = mapind(cur_map, screen);
6786
6787
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47306 times.
✓ Branch 3 taken 54 times.
47360 if(canPermSecret(-1,screen))
6788 {
6789
3/4
✓ Branch 0 taken 47306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6344 times.
✓ Branch 3 taken 40962 times.
47306 if(game->maps[mi]&mSECRET) // if special stuff done before
6790 {
6791
1/2
✓ Branch 0 taken 6344 times.
✗ Branch 1 not taken.
6344 reveal_hidden_stairs(scr, screen, false);
6792 6344 bool from_active_screen = false;
6793 6344 bool do_replay_comment = true;
6794
1/2
✓ Branch 0 taken 6344 times.
✗ Branch 1 not taken.
6344 trigger_secrets_for_screen_internal(screen_handles, from_active_screen, false, -1, do_replay_comment);
6795 6344 }
6796
3/4
✓ Branch 0 taken 47306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47289 times.
✓ Branch 3 taken 17 times.
47306 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6797 {
6798
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 17 times.
136 for (int layer = 0; layer <= 6; layer++)
6799 {
6800 119 mapscr* tscr = &scrs[layer];
6801
2/2
✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 119 times.
21063 for (int pos = 0; pos < 176; pos++)
6802 {
6803 20944 newcombo const* cmb = &combobuf[tscr->data[pos]];
6804
2/2
✓ Branch 0 taken 20927 times.
✓ Branch 1 taken 17 times.
20944 if(cmb->type == cLIGHTTARGET)
6805 {
6806
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!(cmb->usrflags&cflag1)) //Unlit version
6807 {
6808 17 tscr->data[pos] += 1;
6809 17 }
6810 17 }
6811 20944 }
6812 119 }
6813 17 }
6814 47306 }
6815
6816
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 271 times.
✓ Branch 3 taken 47089 times.
47360 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6817 {
6818
1/2
✓ Branch 0 taken 271 times.
✗ Branch 1 not taken.
271 remove_lockblocks(screen_handles);
6819 271 }
6820
6821
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 47359 times.
47360 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6822 {
6823
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6824 1 }
6825
6826
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 106 times.
✓ Branch 3 taken 47254 times.
47360 if(game->maps[mi]&mCHEST) // if special stuff done before
6827 {
6828
1/2
✓ Branch 0 taken 106 times.
✗ Branch 1 not taken.
106 remove_chests(screen_handles);
6829 106 }
6830
6831
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 47336 times.
47360 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6832 {
6833
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 remove_lockedchests(screen_handles);
6834 24 }
6835
6836
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 47360 times.
47360 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6837 {
6838 remove_bosschests(screen_handles);
6839 }
6840
6841
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 clear_xdoors(screen_handles);
6842
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 clear_xstatecombos(screen_handles);
6843
6844 // check doors
6845
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47306 times.
✓ Branch 3 taken 54 times.
47360 if (isdungeon(screen))
6846 {
6847
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 54 times.
270 for(int32_t i=0; i<4; i++)
6848 {
6849 216 int32_t door=scr->door[i];
6850 216 bool putit=true;
6851
6852
4/5
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 139 times.
216 switch(door)
6853 {
6854 case d1WAYSHUTTER:
6855 case dSHUTTER:
6856 61 break;
6857
6858 case dLOCKED:
6859
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(game->maps[mi]&(mDOOR_UP<<i))
6860 {
6861 12 scr->door[i]=dUNLOCKED;
6862 12 }
6863
6864 12 break;
6865
6866 case dBOSS:
6867
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(game->maps[mi]&(mDOOR_UP<<i))
6868 {
6869 scr->door[i]=dOPENBOSS;
6870 }
6871
6872 4 break;
6873
6874 case dBOMB:
6875 if(game->maps[mi]&(mDOOR_UP<<i))
6876 {
6877 scr->door[i]=dBOMBED;
6878 }
6879
6880 break;
6881 }
6882
6883
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(putit)
6884 {
6885
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 putdoor(scr, scrollbuf, i, scr->door[i], false);
6886 216 }
6887
6888
3/4
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
216 if(door==dSHUTTER||door==d1WAYSHUTTER)
6889 {
6890 61 scr->door[i]=door;
6891 61 }
6892 216 }
6893 54 }
6894
6895
2/2
✓ Branch 0 taken 331520 times.
✓ Branch 1 taken 47360 times.
378880 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6896 {
6897
4/4
✓ Branch 0 taken 284160 times.
✓ Branch 1 taken 47360 times.
✓ Branch 2 taken 74659 times.
✓ Branch 3 taken 209501 times.
331520 if (j < 0 || scr->layermap[j] > 0)
6898 {
6899
2/2
✓ Branch 0 taken 74659 times.
✓ Branch 1 taken 47360 times.
122019 mapscr *layerscreen= (j<0 ? scr
6900 74659 : &(TheMaps[(scr->layermap[j]-1)*MAPSCRS+scr->layerscreen[j]]));
6901
6902
2/2
✓ Branch 0 taken 21475344 times.
✓ Branch 1 taken 122019 times.
21597363 for(int32_t i=0; i<176; ++i)
6903 {
6904 21475344 int32_t c=layerscreen->data[i];
6905
6906 // New screen flag: Cycle Combos At Screen Init
6907
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 21475344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
21475344 if((scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6908 {
6909 int32_t r = 0;
6910
6911 while(combobuf[c].can_cycle() && r++ < 10)
6912 {
6913 newcombo const& cmb = combobuf[c];
6914 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6915 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6916 layerscreen->data[i] = cid;
6917 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6918 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6919 c = layerscreen->data[i];
6920 }
6921 }
6922 21475344 }
6923 122019 }
6924 331520 }
6925
6926 47360 return scrs;
6927
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 }
6928
6929 19767273 void putscr(mapscr* scr, BITMAP* dest, int32_t x, int32_t y)
6930 {
6931 // This is a bogus value while screenscrolling == true, but that's ok
6932 // because it is only used to calculate the rpos, and during screenscrolling
6933 // only the modulus to get pos (draw_cmb_pos does RPOS_TO_POS) is needed, which
6934 // is always the same no matter the value of scr.
6935 19767273 int screen = get_screen_for_world_xy(x, y);
6936
6937 19767273 x -= viewport.x;
6938 19767273 y -= viewport.y;
6939
6940
3/6
✓ Branch 0 taken 19767273 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19767273 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19767273 times.
19767273 if (!scr->is_valid()||!show_layers[0]||scr->hidelayers & 1)
6941 {
6942 rectfill(dest,x,y,x+255,y+175,0);
6943 return;
6944 }
6945
6946 39387079 bool over = XOR(scr->flags7&fLAYER2BG,DMaps[cur_dmap].flags&dmfLAYER2BG)
6947
2/2
✓ Branch 0 taken 19619806 times.
✓ Branch 1 taken 147467 times.
19767273 || XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
6948
2/2
✓ Branch 0 taken 243651 times.
✓ Branch 1 taken 19376155 times.
19619806 || !get_qr(qr_CLASSIC_DRAWING_ORDER);
6949
6950 int start_x, end_x, start_y, end_y;
6951 19767273 get_bounds_for_draw_cmb_calls(dest, x, y, start_x, end_x, start_y, end_y);
6952
2/2
✓ Branch 0 taken 19767273 times.
✓ Branch 1 taken 210538677 times.
230305950 for (int cy = start_y; cy < end_y; cy++)
6953 {
6954
2/2
✓ Branch 0 taken 3196617058 times.
✓ Branch 1 taken 210538677 times.
3407155735 for (int cx = start_x; cx < end_x; cx++)
6955 {
6956 3196617058 int i = cx + cy*16;
6957
2/2
✓ Branch 0 taken 374288294 times.
✓ Branch 1 taken 2822328764 times.
3196617058 auto rpos = screenscrolling ? rpos_t::None : POS_TO_RPOS(i, screen);
6958 3196617058 draw_cmb_pos(dest, x + cx*16, y + cy*16, rpos, scr->data[i], scr->cset[i], 0, over, false);
6959 3196617058 }
6960 210538677 }
6961 19767273 }
6962
6963 16133370 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y)
6964 {
6965
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16133370 times.
16133370 if (!show_layers[0])
6966 {
6967 return;
6968 }
6969
6970 16133370 x -= viewport.x;
6971 16133370 y -= viewport.y;
6972
6973
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16133370 times.
32403058 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
6974 16269688 mapscr* scr = screen_handles[0].base_scr;
6975
1/2
✓ Branch 0 taken 16269688 times.
✗ Branch 1 not taken.
16269688 if (!scr->is_valid())
6976 return;
6977
6978
2/2
✓ Branch 0 taken 123411 times.
✓ Branch 1 taken 16146277 times.
16269688 if(scr->door[0]==dBOMBED)
6979 {
6980 123411 over_door(scr, dest, 39, up, offx+x, offy+y);
6981 123411 }
6982
6983
2/2
✓ Branch 0 taken 143109 times.
✓ Branch 1 taken 16126579 times.
16269688 if(scr->door[1]==dBOMBED)
6984 {
6985 143109 over_door(scr, dest, 135, down, offx+x, offy+y);
6986 143109 }
6987
6988
2/2
✓ Branch 0 taken 155862 times.
✓ Branch 1 taken 16113826 times.
16269688 if(scr->door[2]==dBOMBED)
6989 {
6990 155862 over_door(scr, dest, 66, left, offx+x, offy+y);
6991 155862 }
6992
6993
2/2
✓ Branch 0 taken 132289 times.
✓ Branch 1 taken 16137399 times.
16269688 if(scr->door[3]==dBOMBED)
6994 {
6995 132289 over_door(scr, dest, 77, right, offx+x, offy+y);
6996 132289 }
6997 16269688 });
6998 16133370 }
6999
7000 3497585 void putscrdoors(mapscr* scr, BITMAP *dest, int32_t x, int32_t y)
7001 {
7002
2/4
✓ Branch 0 taken 3497585 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3497585 times.
✗ Branch 3 not taken.
3497585 if (!scr->is_valid() || !show_layers[0])
7003 return;
7004
7005 3497585 x -= viewport.x;
7006 3497585 y -= viewport.y;
7007
7008
2/2
✓ Branch 0 taken 37656 times.
✓ Branch 1 taken 3459929 times.
3497585 if(scr->door[0]==dBOMBED)
7009 {
7010 37656 over_door(scr,dest,39,up,x,y);
7011 37656 }
7012
7013
2/2
✓ Branch 0 taken 36495 times.
✓ Branch 1 taken 3461090 times.
3497585 if(scr->door[1]==dBOMBED)
7014 {
7015 36495 over_door(scr,dest,135,down,x,y);
7016 36495 }
7017
7018
2/2
✓ Branch 0 taken 40440 times.
✓ Branch 1 taken 3457145 times.
3497585 if(scr->door[2]==dBOMBED)
7019 {
7020 40440 over_door(scr,dest,66,left,x,y);
7021 40440 }
7022
7023
2/2
✓ Branch 0 taken 37063 times.
✓ Branch 1 taken 3460522 times.
3497585 if(scr->door[3]==dBOMBED)
7024 {
7025 37063 over_door(scr,dest,77,right,x,y);
7026 37063 }
7027 3497585 }
7028 262958206 static inline bool standing_on_z(newcombo const& cmb, zfix const& standing_z_state)
7029 {
7030
1/2
✓ Branch 0 taken 262958206 times.
✗ Branch 1 not taken.
262958206 if (cmb.dive_under_level)
7031 {
7032 if (standing_z_state <= -cmb.dive_under_level)
7033 return true;
7034 }
7035
7036 262958206 zfix cmb_z, cmb_z_step;
7037
4/4
✓ Branch 0 taken 92789 times.
✓ Branch 1 taken 262865417 times.
✓ Branch 2 taken 88819 times.
✓ Branch 3 taken 3970 times.
262958206 if(cmb.type == cCSWITCHBLOCK && (cmb.usrflags & cflag9))
7038 {
7039 3970 cmb_z = zslongToFix(cmb.attributes[2]);
7040
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3970 times.
3970 cmb_z_step = zslongToFix(zc_max(0,cmb.attributes[3]));
7041 3970 }
7042
2/2
✓ Branch 0 taken 1983 times.
✓ Branch 1 taken 262952253 times.
262954236 else if(cmb.genflags & cflag3)
7043 {
7044 1983 cmb_z = cmb.z_height;
7045
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1983 times.
1983 cmb_z_step = zc_max(0_zf,cmb.z_step_height);
7046 1983 }
7047 262952253 else return false;
7048
7049
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5953 times.
5953 if (standing_z_state == STANDING_Z_MAX) // 'infinity'
7050 return true;
7051
2/2
✓ Branch 0 taken 1149 times.
✓ Branch 1 taken 4804 times.
5953 if (!cmb_z) return false; // infinite height
7052
7053 4804 return (cmb_z - cmb_z_step) <= standing_z_state;
7054 262958206 }
7055 62155915 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt)
7056 {
7057 62155915 return _walkflag(zx,zy,cnt,0_zf);
7058 }
7059
7060 142617942 bool _walkflag_new(const mapscr* s0, const mapscr* s1, const mapscr* s2, zfix_round zx, zfix_round zy, zfix const& standing_z_state, bool is_temp_screens)
7061 {
7062 142617942 int x = zx.getRound(), y = zy.getRound();
7063 142617942 int pos = COMBOPOS(x % 256, y % 176);
7064 142617942 const newcombo& c = combobuf[s0->data[pos]];
7065 142617942 const newcombo& c1 = combobuf[s1->data[pos]];
7066 142617942 const newcombo& c2 = combobuf[s2->data[pos]];
7067
4/4
✓ Branch 0 taken 140526316 times.
✓ Branch 1 taken 2091626 times.
✓ Branch 2 taken 140516856 times.
✓ Branch 3 taken 9460 times.
285465874 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
7068
4/4
✓ Branch 0 taken 114995 times.
✓ Branch 1 taken 140631851 times.
✓ Branch 2 taken 2211836 times.
✓ Branch 3 taken 4245 times.
142617942 (iswater_type(c2.type))) && DRIEDLAKE);
7069 142847932 int32_t b=1;
7070
2/2
✓ Branch 0 taken 70427616 times.
✓ Branch 1 taken 72420316 times.
142847932 if(x&8) b<<=2;
7071
2/2
✓ Branch 0 taken 66774470 times.
✓ Branch 1 taken 76073462 times.
142847932 if(y&8) b<<=1;
7072
7073 142847932 int32_t cwalkflag = c.walk;
7074
4/4
✓ Branch 0 taken 142732928 times.
✓ Branch 1 taken 115004 times.
✓ Branch 2 taken 142732764 times.
✓ Branch 3 taken 164 times.
142847932 if(is_temp_screens && standing_on_z(c,standing_z_state)) cwalkflag &= (c.walk>>4)^0xF;
7075
8/10
✓ Branch 0 taken 57502 times.
✓ Branch 1 taken 142790266 times.
✓ Branch 2 taken 2206612 times.
✓ Branch 3 taken 2149110 times.
✓ Branch 4 taken 2206612 times.
✓ Branch 5 taken 142732764 times.
✓ Branch 6 taken 2206612 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2206612 times.
✗ Branch 9 not taken.
142847768 else if ((c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) || (iswater_type(c.type) && ((c.walk>>4)&b) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
7076
2/2
✓ Branch 0 taken 63216551 times.
✓ Branch 1 taken 79516377 times.
142732928 if (s1 != s0)
7077 {
7078
3/4
✓ Branch 0 taken 79516377 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 79515759 times.
✓ Branch 3 taken 618 times.
79516377 if(is_temp_screens && standing_on_z(c1,standing_z_state)) cwalkflag &= (c1.walk>>4)^0xF;
7079
4/10
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 79504030 times.
✓ Branch 2 taken 11729 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11729 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
79515759 else if ((iswater_type(c1.type) && ((c1.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_1) && !((c1.usrflags&cflag3) || (c1.usrflags&cflag4)))) cwalkflag &= c1.walk;
7080
2/2
✓ Branch 0 taken 71255 times.
✓ Branch 1 taken 79444504 times.
79515759 else if (c1.type == cBRIDGE)
7081 {
7082
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71255 times.
71255 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
7083 {
7084 71255 int efflag = (c1.walk & 0xF0)>>4;
7085 71255 int newsolid = (c1.walk & 0xF);
7086 71255 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
7087 71255 }
7088 else cwalkflag &= c1.walk;
7089 71255 }
7090
3/8
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 79432775 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11729 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
79444504 else if ((iswater_type(c1.type) && get_qr(qr_WATER_ON_LAYER_1) && ((c1.usrflags&cflag3) || (c1.usrflags&cflag4)) && ((c1.walk>>4)&b))) cwalkflag = 0;
7091 79444504 else cwalkflag |= c1.walk;
7092 79516377 }
7093
2/2
✓ Branch 0 taken 102024027 times.
✓ Branch 1 taken 40708901 times.
142732928 if (s2 != s0)
7094 {
7095
2/4
✓ Branch 0 taken 40708901 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40708901 times.
✗ Branch 3 not taken.
40708901 if(is_temp_screens && standing_on_z(c2,standing_z_state)) cwalkflag &= (c2.walk>>4)^0xF;
7096
7/10
✓ Branch 0 taken 5889 times.
✓ Branch 1 taken 40703012 times.
✓ Branch 2 taken 5889 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3735 times.
✓ Branch 5 taken 2154 times.
✓ Branch 6 taken 3735 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 3735 times.
40708901 else if ((iswater_type(c2.type) && ((c2.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_2) && !((c2.usrflags&cflag3) || (c2.usrflags&cflag4)))) cwalkflag &= c2.walk;
7097
2/2
✓ Branch 0 taken 16725 times.
✓ Branch 1 taken 40688441 times.
40705166 else if (c2.type == cBRIDGE)
7098 {
7099
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16725 times.
16725 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
7100 {
7101 16725 int efflag = (c2.walk & 0xF0)>>4;
7102 16725 int newsolid = (c2.walk & 0xF);
7103 16725 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
7104 16725 }
7105 else cwalkflag &= c2.walk;
7106 16725 }
7107
3/8
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 40686287 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2154 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
40688441 else if ((iswater_type(c2.type) && get_qr(qr_WATER_ON_LAYER_2) && ((c2.usrflags&cflag3) || (c2.usrflags&cflag4))) && ((c2.walk>>4)&b)) cwalkflag = 0;
7108 40688441 else cwalkflag |= c2.walk;
7109 40708901 }
7110
7111
4/4
✓ Branch 0 taken 30808240 times.
✓ Branch 1 taken 111924688 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 30807292 times.
142732928 if((cwalkflag&b) && !dried)
7112 30807292 return true;
7113
7114
3/4
✓ Branch 0 taken 111925636 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 111856446 times.
✓ Branch 3 taken 69190 times.
111925636 if (is_temp_screens && collide_object(zx, zy, 0.0001_zf, 0.0001_zf)) return true;
7115
7116 111856446 return false;
7117 142732928 }
7118
7119 // Returns true if the combo at viewport position x,y is solid. Looks at a combo's quadrant walkablity flags.
7120 142732928 static bool _walkflag_new(zfix_round zx, zfix_round zy, zfix const& standing_z_state)
7121 {
7122 142732928 int x = zx.getRound(), y = zy.getRound();
7123 142732928 mapscr* s0 = get_scr_for_world_xy_layer(x, y, 0);
7124 142732928 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
7125 142732928 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
7126
2/2
✓ Branch 0 taken 63216551 times.
✓ Branch 1 taken 79516377 times.
142732928 if (!s1->valid) s1 = s0;
7127
2/2
✓ Branch 0 taken 102024027 times.
✓ Branch 1 taken 40708901 times.
142732928 if (!s2->valid) s2 = s0;
7128 142732928 return _walkflag_new(s0, s1, s2, zx, zy, standing_z_state, true);
7129 }
7130
7131 138205051 bool _walkflag(zfix_round x,zfix_round y,int32_t cnt,zfix const& standing_z_state)
7132 {
7133 138205051 int max_x = world_w;
7134 138205051 int max_y = world_h;
7135
2/2
✓ Branch 0 taken 78162314 times.
✓ Branch 1 taken 60042737 times.
138205051 if (!get_qr(qr_LTTPWALK))
7136 {
7137 60042737 max_x -= 7;
7138 60042737 max_y -= 7;
7139 60042737 }
7140
4/4
✓ Branch 0 taken 137932683 times.
✓ Branch 1 taken 272368 times.
✓ Branch 2 taken 83268 times.
✓ Branch 3 taken 137849415 times.
138205051 if (x < 0 || y < 0) return false;
7141
2/2
✓ Branch 0 taken 323548 times.
✓ Branch 1 taken 137525867 times.
137849415 if (x >= max_x) return false;
7142
3/4
✓ Branch 0 taken 571808 times.
✓ Branch 1 taken 136954059 times.
✓ Branch 2 taken 571808 times.
✗ Branch 3 not taken.
137525867 if (x >= max_x - 8 && cnt == 2) return false;
7143
2/2
✓ Branch 0 taken 136971604 times.
✓ Branch 1 taken 554263 times.
137525867 if (y >= max_y) return false;
7144
7145
4/4
✓ Branch 0 taken 30758247 times.
✓ Branch 1 taken 106213357 times.
✓ Branch 2 taken 100452033 times.
✓ Branch 3 taken 5761324 times.
136971604 return _walkflag_new(x, y, standing_z_state) || (cnt != 1 && _walkflag_new(x + 8, y, standing_z_state));
7146 138205051 }
7147
7148 105155278 static bool effectflag(int32_t x, int32_t y, int32_t layer)
7149 {
7150 105155278 mapscr* s0 = get_scr_for_world_xy(x, y);
7151 105155278 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
7152 105155278 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
7153
2/2
✓ Branch 0 taken 57655235 times.
✓ Branch 1 taken 47500043 times.
105155278 if (!s1->valid) s1 = s0;
7154
2/2
✓ Branch 0 taken 24622036 times.
✓ Branch 1 taken 80533242 times.
105155278 if (!s2->valid) s2 = s0;
7155
7156 105155278 int pos = COMBOPOS(x % 256, y % 176);
7157 105155278 const newcombo& c = combobuf[s0->data[pos]];
7158 105155278 const newcombo& c1 = combobuf[s1->data[pos]];
7159 105155278 const newcombo& c2 = combobuf[s2->data[pos]];
7160
4/4
✓ Branch 0 taken 104159574 times.
✓ Branch 1 taken 995704 times.
✓ Branch 2 taken 104158294 times.
✓ Branch 3 taken 1280 times.
210310556 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
7161
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 104158294 times.
✓ Branch 2 taken 995300 times.
✓ Branch 3 taken 1684 times.
105155278 (iswater_type(c2.type))) && DRIEDLAKE);
7162 105155278 int32_t b=1;
7163
2/2
✓ Branch 0 taken 53215572 times.
✓ Branch 1 taken 51939706 times.
105155278 if(x&8) b<<=2;
7164
2/2
✓ Branch 0 taken 44691957 times.
✓ Branch 1 taken 60463321 times.
105155278 if(y&8) b<<=1;
7165
7166 105155278 int32_t cwalkflag = (c.walk>>4);
7167
2/2
✓ Branch 0 taken 80384921 times.
✓ Branch 1 taken 24770357 times.
105155278 if (layer == 0) cwalkflag = (c1.walk>>4);
7168
2/2
✓ Branch 0 taken 80386515 times.
✓ Branch 1 taken 24768763 times.
105155278 if (layer == 1) cwalkflag = (c2.walk>>4);
7169 //if (c.type == cBRIDGE || (iswater_type(c.type) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
7170
4/4
✓ Branch 0 taken 57655235 times.
✓ Branch 1 taken 47500043 times.
✓ Branch 2 taken 24571560 times.
✓ Branch 3 taken 33083675 times.
105155278 if (s1 != s0 && layer < 0)
7171 {
7172
2/2
✓ Branch 0 taken 24555346 times.
✓ Branch 1 taken 16214 times.
24571560 if (c1.type == cBRIDGE) cwalkflag &= (~(c1.walk>>4));
7173 24571560 }
7174
4/4
✓ Branch 0 taken 24622036 times.
✓ Branch 1 taken 80533242 times.
✓ Branch 2 taken 17773115 times.
✓ Branch 3 taken 6848921 times.
105155278 if (s2 != s0 && layer < 1)
7175 {
7176
2/2
✓ Branch 0 taken 17761231 times.
✓ Branch 1 taken 11884 times.
17773115 if (c2.type == cBRIDGE) cwalkflag &= (~(c2.walk>>4));
7177 17773115 }
7178
7179
2/2
✓ Branch 0 taken 104977274 times.
✓ Branch 1 taken 178004 times.
105155278 return (cwalkflag&b) ? !dried : false;
7180 }
7181
7182 105528602 bool _effectflag(int32_t x,int32_t y,int32_t cnt, int32_t layer, bool notLink)
7183 {
7184 DCHECK(cnt == 0 || cnt == 1);
7185 105528602 int max_x = world_w;
7186 105528602 int max_y = world_h;
7187
3/4
✓ Branch 0 taken 45833723 times.
✓ Branch 1 taken 59694879 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45833723 times.
105528602 if (!get_qr(qr_LTTPWALK) && !notLink)
7188 {
7189 45833723 max_x -= 7;
7190 45833723 max_y -= 7;
7191 45833723 }
7192
4/4
✓ Branch 0 taken 105527850 times.
✓ Branch 1 taken 752 times.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 105527646 times.
105528602 if (x < 0 || y < 0) return false;
7193
2/2
✓ Branch 0 taken 816 times.
✓ Branch 1 taken 105526830 times.
105527646 if (x >= max_x) return false;
7194
3/4
✓ Branch 0 taken 526426 times.
✓ Branch 1 taken 105000404 times.
✓ Branch 2 taken 526426 times.
✗ Branch 3 not taken.
105526830 if (x >= max_x - 8 && cnt == 2) return false;
7195
2/2
✓ Branch 0 taken 371552 times.
✓ Branch 1 taken 105155278 times.
105526830 if (y >= max_y) return false;
7196
7197
3/4
✓ Branch 0 taken 104976484 times.
✓ Branch 1 taken 178794 times.
✓ Branch 2 taken 178794 times.
✗ Branch 3 not taken.
105155278 return effectflag(x, y, layer) || (cnt == 2 && effectflag(x + 8, y, layer));
7198 105528602 }
7199
7200 // used by mapdata->isSolid(x,y) in ZScript
7201 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7202 {
7203 int x = zx.getRound(), y = zy.getRound();
7204 {
7205 int max_x = 256;
7206 int max_y = 176;
7207 if (!get_qr(qr_LTTPWALK))
7208 {
7209 max_x -= 7;
7210 max_y -= 7;
7211 }
7212 if (x < 0 || y < 0) return false;
7213 if (x >= max_x) return false;
7214 if (x >= max_x - 8 && cnt == 2) return false;
7215 if (y >= max_y) return false;
7216 }
7217
7218 const mapscr *s1, *s2;
7219 s1 = s2 = m;
7220
7221 if ( m->layermap[0] > 0 && m->layermap[0] <= map_count )
7222 {
7223 const mapscr* s = get_canonical_scr(m->layermap[0] - 1, m->layerscreen[0]);
7224 if (s->is_valid())
7225 s1 = s;
7226 }
7227
7228 if ( m->layermap[1] > 0 && m->layermap[1] <= map_count )
7229 {
7230 const mapscr* s = get_canonical_scr(m->layermap[1] - 1, m->layerscreen[1]);
7231 if (s->is_valid())
7232 s2 = s;
7233 }
7234
7235 zfix unused;
7236 return _walkflag_new(m, s1, s2, x, y, unused, false) || (cnt != 1 && _walkflag_new(m, s1, s2, x + 8, y, unused, false));
7237 }
7238
7239 bool _walkflag_layer(zfix_round x, zfix_round y, int32_t layer, int32_t cnt)
7240 {
7241 DCHECK_LAYER_NEG1_INDEX(layer);
7242 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7243 if (!m->is_valid()) return false;
7244 return _walkflag_layer(x, y, cnt, m);
7245 }
7246
7247 static bool _walkflag_layer_new(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m, int max_x, int max_y)
7248 {
7249 int x = zx.getRound(), y = zy.getRound();
7250
7251 if (!get_qr(qr_LTTPWALK))
7252 {
7253 max_x -= 7;
7254 max_y -= 7;
7255 }
7256 if (x < 0 || y < 0) return false;
7257 if (x >= max_x) return false;
7258 if (x >= max_x - 8 && cnt == 2) return false;
7259 if (y >= max_y) return false;
7260
7261 if(!m) return true;
7262
7263 int pos = COMBOPOS(x%256, y%176);
7264 const newcombo* c = &combobuf[m->data[pos]];
7265 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7266 int32_t b=1;
7267
7268 if(x&8) b<<=2;
7269
7270 if(y&8) b<<=1;
7271
7272 if((c->walk&b) && !dried)
7273 return true;
7274
7275 if(cnt==1) return false;
7276
7277 ++pos;
7278
7279 if(!(x&8))
7280 b<<=2;
7281 else
7282 {
7283 c = &combobuf[m->data[pos]];
7284 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7285 b=1;
7286
7287 if(y&8) b<<=1;
7288 }
7289
7290 return (c->walk&b) ? !dried : false;
7291 }
7292
7293 //Only check the given mapscr*, not its layer 1&2
7294 bool _walkflag_layer(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7295 {
7296 return _walkflag_layer_new(zx, zy, cnt, m, world_w, world_h);
7297 }
7298
7299 bool _walkflag_layer_scrolling(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7300 {
7301 return _walkflag_layer_new(zx, zy, cnt, m, scrolling_region.width, scrolling_region.height);
7302 }
7303
7304 447898 bool _effectflag_layer(int32_t x, int32_t y, int32_t layer, int32_t cnt, bool notLink)
7305 {
7306 DCHECK_LAYER_NEG1_INDEX(layer);
7307 447898 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7308
2/2
✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 446136 times.
447898 if (!m->is_valid()) return false;
7309 446136 return _effectflag_layer(x, y, cnt, m, notLink);
7310 447898 }
7311
7312 519213 bool _effectflag_layer(int32_t x,int32_t y,int32_t cnt, mapscr* m, bool notLink)
7313 {
7314 519213 int max_x = world_w;
7315 519213 int max_y = world_h;
7316
3/4
✓ Branch 0 taken 50002 times.
✓ Branch 1 taken 469211 times.
✓ Branch 2 taken 50002 times.
✗ Branch 3 not taken.
519213 if (!get_qr(qr_LTTPWALK) && !notLink)
7317 {
7318 max_x -= 7;
7319 max_y -= 7;
7320 }
7321
2/4
✓ Branch 0 taken 519213 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 519213 times.
519213 if (x < 0 || y < 0) return false;
7322
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 519213 times.
519213 if (x >= max_x) return false;
7323
3/4
✓ Branch 0 taken 1342 times.
✓ Branch 1 taken 517871 times.
✓ Branch 2 taken 1342 times.
✗ Branch 3 not taken.
519213 if (x >= max_x - 8 && cnt == 2) return false;
7324
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 519213 times.
519213 if (y >= max_y) return false;
7325
7326
1/2
✓ Branch 0 taken 519213 times.
✗ Branch 1 not taken.
519213 if (!m) return true;
7327
7328 519213 int pos = COMBOPOS(x%256, y%176);
7329 519213 const newcombo* c = &combobuf[m->data[pos]];
7330
3/4
✓ Branch 0 taken 518813 times.
✓ Branch 1 taken 400 times.
✓ Branch 2 taken 400 times.
✗ Branch 3 not taken.
519613 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7331 519213 int32_t b=1;
7332
7333
2/2
✓ Branch 0 taken 276528 times.
✓ Branch 1 taken 242685 times.
519213 if(x&8) b<<=2;
7334
7335
2/2
✓ Branch 0 taken 220331 times.
✓ Branch 1 taken 298882 times.
519213 if(y&8) b<<=1;
7336
7337
3/4
✓ Branch 0 taken 450224 times.
✓ Branch 1 taken 68989 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 450224 times.
519213 if(((c->walk>>4)&b) && !dried)
7338 450224 return true;
7339
7340
1/2
✓ Branch 0 taken 68989 times.
✗ Branch 1 not taken.
68989 if(cnt==1) return false;
7341
7342 ++pos;
7343
7344 if(!(x&8))
7345 b<<=2;
7346 else
7347 {
7348 c = &combobuf[m->data[pos]];
7349 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7350 b=1;
7351
7352 if(y&8) b<<=1;
7353 }
7354
7355 return ((c->walk>>4)&b) ? !dried : false;
7356 519213 }
7357
7358 860420 bool water_walkflag(int32_t x, int32_t y, int32_t cnt)
7359 {
7360 860420 int max_x = world_w;
7361 860420 int max_y = world_h;
7362
2/2
✓ Branch 0 taken 165182 times.
✓ Branch 1 taken 695238 times.
860420 if (!get_qr(qr_LTTPWALK))
7363 {
7364 695238 max_x -= 7;
7365 695238 max_y -= 7;
7366 695238 }
7367
2/4
✓ Branch 0 taken 860420 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 860420 times.
860420 if (x < 0 || y < 0) return false;
7368
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if (x >= max_x) return false;
7369
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
860420 if (x >= max_x - 8 && cnt == 2) return false;
7370
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if (y >= max_y) return false;
7371
7372
3/4
✓ Branch 0 taken 17860 times.
✓ Branch 1 taken 842560 times.
✓ Branch 2 taken 842560 times.
✗ Branch 3 not taken.
860420 return water_walkflag(x, y) || (cnt != 1 && water_walkflag(x + 8, y));
7373 860420 }
7374
7375 860420 bool water_walkflag(int32_t x, int32_t y)
7376 {
7377 860420 const newcombo& c = combobuf[MAPCOMBO2(-1, x, y)];
7378 860420 const newcombo& c1 = combobuf[MAPCOMBO2(0, x, y)];
7379 860420 const newcombo& c2 = combobuf[MAPCOMBO2(1, x, y)];
7380
7381 860420 int32_t b=1;
7382
2/2
✓ Branch 0 taken 439102 times.
✓ Branch 1 taken 421318 times.
860420 if(x&8) b<<=2;
7383
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if(y&8) b<<=1;
7384
7385
2/2
✓ Branch 0 taken 74192 times.
✓ Branch 1 taken 786228 times.
860420 if(get_qr(qr_NO_SOLID_SWIM))
7386 {
7387
2/2
✓ Branch 0 taken 474 times.
✓ Branch 1 taken 73718 times.
74192 if(c.walk&b)
7388 474 return true;
7389
7390
2/2
✓ Branch 0 taken 914 times.
✓ Branch 1 taken 72804 times.
73718 if(c1.walk&b)
7391 914 return true;
7392
7393
2/2
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 72733 times.
72804 if(c2.walk&b)
7394 71 return true;
7395 72733 }
7396 else
7397 {
7398
4/4
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 750095 times.
✓ Branch 2 taken 19762 times.
✓ Branch 3 taken 16371 times.
786228 if((c.walk&b) && !iswater_type(c.type))
7399 16371 return true;
7400
7401
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 769840 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
769857 if((c1.walk&b) && !iswater_type(c1.type))
7402 17 return true;
7403
7404
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 769827 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
769840 if((c2.walk&b) && !iswater_type(c2.type))
7405 13 return true;
7406 }
7407
7408 842560 return false;
7409 860420 }
7410
7411 589885 bool hit_walkflag(int32_t x,int32_t y,int32_t cnt)
7412 {
7413
2/2
✓ Branch 0 taken 100391 times.
✓ Branch 1 taken 489494 times.
589885 if(dlevel)
7414
8/8
✓ Branch 0 taken 488049 times.
✓ Branch 1 taken 1445 times.
✓ Branch 2 taken 484722 times.
✓ Branch 3 taken 3327 times.
✓ Branch 4 taken 483005 times.
✓ Branch 5 taken 1717 times.
✓ Branch 6 taken 4386 times.
✓ Branch 7 taken 478619 times.
489494 if(x<32 || y<40 || (x+(cnt-1)*8)>=world_w-32 || y>=world_h-32)
7415 10875 return true;
7416
7417
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 579008 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
579010 if(blockpath && y<((get_qr(qr_LTTPCOLLISION))?80:88))
7418 return true;
7419
7420
8/8
✓ Branch 0 taken 578724 times.
✓ Branch 1 taken 286 times.
✓ Branch 2 taken 578481 times.
✓ Branch 3 taken 243 times.
✓ Branch 4 taken 578270 times.
✓ Branch 5 taken 211 times.
✓ Branch 6 taken 396 times.
✓ Branch 7 taken 577874 times.
579010 if(x<16 || y<16 || (x+(cnt-1)*8)>=world_w-16 || y>=world_h-16)
7421 1136 return true;
7422
7423 // for(int32_t i=0; i<4; i++)
7424
4/4
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 577033 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 805 times.
577874 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7425 36 return true;
7426
7427
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 577837 times.
577838 if (collide_object(x, y,cnt*8, 1))
7428 1 return true;
7429
7430 577837 return _walkflag(x,y,cnt);
7431 589885 }
7432
7433 12220 bool solpush_walkflag(int32_t x, int32_t y, int32_t cnt, solid_object const* ign)
7434 {
7435 // 16 pixel buffer to account for slopes that are on bordering screens.
7436
4/8
✓ Branch 0 taken 12220 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12220 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12220 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12220 times.
12220 if(x<0 || y<0 || x>=world_w+16 || y>=world_h+16)
7437 return true;
7438
7439 // for(int32_t i=0; i<4; i++)
7440
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12220 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12220 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7441 return true;
7442
7443
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12220 times.
12220 if (collide_object(x, y,cnt*8, 1, ign))
7444 return true;
7445
7446 12220 return _walkflag(x,y,cnt);
7447 12220 }
7448
7449 39588 void map_bkgsfx(bool on)
7450 {
7451
2/2
✓ Branch 0 taken 39567 times.
✓ Branch 1 taken 21 times.
39588 if(on)
7452 {
7453 39567 cont_sfx(hero_scr->oceansfx);
7454
7455
4/4
✓ Branch 0 taken 369 times.
✓ Branch 1 taken 39198 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 54 times.
39567 if(hero_scr->bosssfx && !(game->lvlitems[dlevel]&(1 << li_boss_killed)))
7456 315 cont_sfx(hero_scr->bosssfx);
7457 39567 }
7458 else
7459 {
7460 21 adjust_sfx(hero_scr->oceansfx,128,false);
7461 21 adjust_sfx(hero_scr->bosssfx,128,false);
7462
7463
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 21 times.
135 for(int32_t i=0; i<guys.Count(); i++)
7464 {
7465
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 84 times.
114 if(((enemy*)guys.spr(i))->bgsfx)
7466 84 stop_sfx(((enemy*)guys.spr(i))->bgsfx);
7467 114 }
7468 }
7469 39588 }
7470
7471 261 void toggle_switches(dword flags, bool entry)
7472 {
7473
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 261 times.
261 if(!flags) return; //No flags to toggle
7474
7475 522 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7476 261 toggle_switches(flags, entry, create_screen_handles(scr));
7477 261 });
7478 261 }
7479 55204 void toggle_switches(dword flags, bool entry, const screen_handles_t& screen_handles)
7480 {
7481
2/2
✓ Branch 0 taken 931 times.
✓ Branch 1 taken 54273 times.
55204 if(!flags) return; //No flags to toggle
7482
7483 931 mapscr* m = screen_handles[0].base_scr;
7484 931 int screen = m->screen;
7485 931 bool is_active_screen = is_in_current_region(m);
7486
7487 525235 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
7488 524304 byte togglegrid[176] = {0};
7489 524304 mapscr* scr = rpos_handle.scr;
7490 524304 int lyr = rpos_handle.layer;
7491 524304 int pos = rpos_handle.pos;
7492 524304 newcombo const& cmb = combobuf[scr->data[pos]];
7493
2/2
✓ Branch 0 taken 39424 times.
✓ Branch 1 taken 484880 times.
524304 if(is_active_screen)
7494
1/2
✓ Branch 0 taken 484880 times.
✗ Branch 1 not taken.
641011 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7495
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 156131 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
156131 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7496 }, ctrigSWITCHSTATE);
7497
3/4
✓ Branch 0 taken 523592 times.
✓ Branch 1 taken 712 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2809 times.
524304 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32
7498
2/2
✓ Branch 0 taken 2809 times.
✓ Branch 1 taken 521495 times.
524304 && !(cmb.usrflags & cflag11)) //global state
7499 {
7500
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2363 times.
2809 if(flags&(1<<cmb.attribytes[0]))
7501 {
7502 2363 set<int32_t> oldData;
7503 //Increment the combo/cset by the attributes
7504 2363 int32_t cmbofs = (cmb.attributes[0]/10000L);
7505 2363 int32_t csofs = (cmb.attributes[1]/10000L);
7506
1/2
✓ Branch 0 taken 2363 times.
✗ Branch 1 not taken.
2363 oldData.insert(scr->data[pos]);
7507
1/2
✓ Branch 0 taken 2363 times.
✗ Branch 1 not taken.
2363 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7508 2363 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7509
4/4
✓ Branch 0 taken 1444 times.
✓ Branch 1 taken 919 times.
✓ Branch 2 taken 1206 times.
✓ Branch 3 taken 238 times.
2363 if(entry && (cmb.usrflags&cflag8))
7510 {
7511 238 newcombo const* tmp = &combobuf[scr->data[pos]];
7512
2/4
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
238 while(tmp->can_cycle())
7513 {
7514 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7515 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7516 if(oldData.find(cid) != oldData.end())
7517 break;
7518
7519 scr->data[pos] = cid;
7520 if(!(tmp->animflags & AF_CYCLENOCSET))
7521 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7522 oldData.insert(cid);
7523 tmp = &combobuf[cid];
7524 }
7525 238 }
7526 2363 int32_t cmbid = scr->data[pos];
7527
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2322 times.
2363 if(combobuf[cmbid].animflags & AF_CYCLE)
7528 {
7529 41 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7530 41 combobuf[cmbid].cur_frame=0;
7531 41 combobuf[cmbid].aclk = 0;
7532
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 combo_caches::drawing.refresh(cmbid);
7533 41 }
7534 2363 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7535
2/2
✓ Branch 0 taken 560 times.
✓ Branch 1 taken 1803 times.
2363 if(cmb.type == cCSWITCH) return; //Switches don't toggle other layers
7536
2/2
✓ Branch 0 taken 12621 times.
✓ Branch 1 taken 1803 times.
14424 for(int32_t lyr2 = 0; lyr2 < 7; ++lyr2) //Toggle same pos on other layers, if flag set
7537 {
7538
2/2
✓ Branch 0 taken 1803 times.
✓ Branch 1 taken 10818 times.
12621 if(lyr==lyr2) continue;
7539
2/2
✓ Branch 0 taken 344 times.
✓ Branch 1 taken 10474 times.
10818 if(!(cmb.usrflags&(1<<lyr2))) continue;
7540
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(togglegrid[pos]&(1<<lyr2)) continue;
7541
7542 344 mapscr* scr_2 = screen_handles[lyr2].scr;
7543
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(!scr_2->data[pos]) //Don't increment empty space
7544 continue;
7545 344 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7546
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
344 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK) && !(cmb.usrflags & cflag11)
7547 && cmb_2.attribytes[0] < 32 && (flags&(1<<cmb_2.attribytes[0])))
7548 continue; //This is a switch/block that will be hit later in the loop!
7549 344 set<int32_t> oldData2;
7550 //Increment the combo/cset by the original cmb's attributes
7551
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 oldData2.insert(scr_2->data[pos]);
7552
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7553 344 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7554
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
344 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7555 {
7556 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7557 while(tmp->can_cycle())
7558 {
7559 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7560 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7561 if(oldData2.find(cid) != oldData2.end())
7562 break;
7563
7564 scr_2->data[pos] = cid;
7565 if(!(tmp->animflags & AF_CYCLENOCSET))
7566 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7567 oldData2.insert(cid);
7568 tmp = &combobuf[cid];
7569 }
7570 }
7571 344 int32_t cmbid2 = scr_2->data[pos];
7572
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(combobuf[cmbid2].animflags & AF_CYCLE)
7573 {
7574 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7575 combobuf[cmbid2].cur_frame=0;
7576 combobuf[cmbid2].aclk = 0;
7577 combo_caches::drawing.refresh(cmbid2);
7578 }
7579 344 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7580 344 }
7581
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 560 times.
✓ Branch 2 taken 1803 times.
2363 }
7582 2249 }
7583 524304 });
7584
7585
3/4
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 412 times.
✓ Branch 2 taken 519 times.
✗ Branch 3 not taken.
931 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7586 {
7587 newcombo const& cmb = combobuf[mblock2.bcombo];
7588 if(!(cmb.usrflags & cflag11) && (cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32)
7589 {
7590 if(flags&(1<<cmb.attribytes[0]))
7591 {
7592 //Increment the combo/cset by the attributes
7593 int32_t cmbofs = (cmb.attributes[0]/10000L);
7594 int32_t csofs = (cmb.attributes[1]/10000L);
7595 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7596 mblock2.cs = (mblock2.cs + csofs) & 15;
7597 int32_t cmbid = mblock2.bcombo;
7598 if(combobuf[cmbid].animflags & AF_CYCLE)
7599 {
7600 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7601 combobuf[cmbid].cur_frame=0;
7602 combobuf[cmbid].aclk = 0;
7603 combo_caches::drawing.refresh(cmbid);
7604 }
7605 }
7606 }
7607 }
7608
7609
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 707 times.
931 if (is_active_screen)
7610 {
7611 707 int screen_index_offset = get_region_screen_offset(m->screen);
7612 707 word c = m->numFFC();
7613
2/2
✓ Branch 0 taken 565 times.
✓ Branch 1 taken 707 times.
1272 for (int q = 0; q < c; ++q)
7614 {
7615 565 auto ffc_handle = *m->getFFCHandle(q, screen_index_offset);
7616
1/2
✓ Branch 0 taken 565 times.
✗ Branch 1 not taken.
596 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7617
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
31 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7618 }, ctrigSWITCHSTATE);
7619 565 }
7620 707 }
7621 55204 }
7622
7623 1 void toggle_gswitches(int32_t state, bool entry)
7624 {
7625 2 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7626 1 toggle_gswitches(state, entry, create_screen_handles(scr));
7627 1 });
7628 1 }
7629 1 void toggle_gswitches(int32_t state, bool entry, const screen_handles_t& screen_handles)
7630 {
7631 1 bool states[256] = {false};
7632 1 states[state] = true;
7633 1 toggle_gswitches(states, entry, screen_handles);
7634 1 }
7635 15796484 void toggle_gswitches(bool* states, bool entry, const screen_handles_t& screen_handles)
7636 {
7637
1/2
✓ Branch 0 taken 15796484 times.
✗ Branch 1 not taken.
15796484 if(!states) return;
7638
7639 15796484 auto& combo_cache = combo_caches::gswitch;
7640 15796484 mapscr* base_scr = screen_handles[0].base_scr;
7641 15796484 int screen = base_scr->screen;
7642 15796484 bool is_active_screen = is_in_current_region(base_scr);
7643 15796484 byte togglegrid[176] = {0};
7644
2/2
✓ Branch 0 taken 15796484 times.
✓ Branch 1 taken 110575388 times.
126371872 for(int32_t lyr = 0; lyr <= 6; ++lyr)
7645 {
7646 110575388 mapscr* scr = screen_handles[lyr].scr;
7647
2/2
✓ Branch 0 taken 35899510 times.
✓ Branch 1 taken 74675878 times.
110575388 if (!scr)
7648 74675878 continue;
7649
7650
2/2
✓ Branch 0 taken 35899510 times.
✓ Branch 1 taken 6318313760 times.
6354213270 for(int32_t pos = 0; pos < 176; ++pos)
7651 {
7652 6318313760 int cid = scr->data[pos];
7653 6318313760 auto& mini_cmb = combo_cache.minis[cid];
7654
7655
2/2
✓ Branch 0 taken 2910336 times.
✓ Branch 1 taken 6315403424 times.
6318313760 if (is_active_screen)
7656 {
7657
2/2
✓ Branch 0 taken 6315401542 times.
✓ Branch 1 taken 1882 times.
6315403424 if (mini_cmb.trigger_global_state)
7658 {
7659 1882 auto rpos_handle = get_rpos_handle_for_screen(screen, lyr, pos);
7660
1/2
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
3764 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7661
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1882 times.
1882 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7662 }, ctrigSWITCHSTATE);
7663 1882 }
7664 6315403424 }
7665
7666
2/2
✓ Branch 0 taken 55356 times.
✓ Branch 1 taken 6318258404 times.
6318313760 if (!mini_cmb.has_global_state)
7667 6318258404 continue;
7668
7669 55356 newcombo const& cmb = combobuf[cid];
7670
2/4
✓ Branch 0 taken 55356 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 55356 times.
55356 if(cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK)
7671 {
7672 if(states[cmb.attribytes[0]])
7673 {
7674 set<int32_t> oldData;
7675 //Increment the combo/cset by the attributes
7676 int32_t cmbofs = (cmb.attributes[0]/10000L);
7677 int32_t csofs = (cmb.attributes[1]/10000L);
7678 oldData.insert(scr->data[pos]);
7679 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7680 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7681 if(entry && (cmb.usrflags&cflag8))
7682 {
7683 newcombo const* tmp = &combobuf[scr->data[pos]];
7684 while(tmp->can_cycle())
7685 {
7686 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7687 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7688 if(oldData.find(cid) != oldData.end())
7689 break;
7690 scr->data[pos] = cid;
7691 if(!(tmp->animflags & AF_CYCLENOCSET))
7692 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7693 oldData.insert(cid);
7694 tmp = &combobuf[cid];
7695 }
7696 }
7697 int32_t cmbid = scr->data[pos];
7698 if(combobuf[cmbid].animflags & AF_CYCLE)
7699 {
7700 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7701 combobuf[cmbid].cur_frame=0;
7702 combobuf[cmbid].aclk = 0;
7703 combo_caches::drawing.refresh(cmbid);
7704 }
7705 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7706 if(cmb.type == cCSWITCH) continue; //Switches don't toggle other layers
7707 for(int32_t lyr2 = 0; lyr2 <= 6; ++lyr2) //Toggle same pos on other layers, if flag set
7708 {
7709 if(lyr==lyr2) continue;
7710 if(!(cmb.usrflags&(1<<lyr2))) continue;
7711 if(togglegrid[pos]&(1<<lyr2)) continue;
7712 mapscr* scr_2 = lyr2 == 0 ? base_scr : get_scr_layer_valid(screen, lyr2);
7713 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7714 continue;
7715 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7716 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK)
7717 && (cmb_2.usrflags & cflag11) && (states[cmb_2.attribytes[0]]))
7718 continue; //This is a switch/block that will be hit later in the loop!
7719 set<int32_t> oldData2;
7720 //Increment the combo/cset by the original cmb's attributes
7721 oldData2.insert(scr_2->data[pos]);
7722 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7723 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7724 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7725 {
7726 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7727 while(tmp->can_cycle())
7728 {
7729 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7730 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7731 if(oldData2.find(cid) != oldData2.end())
7732 break;
7733 scr_2->data[pos] = cid;
7734 if(!(tmp->animflags & AF_CYCLENOCSET))
7735 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7736 oldData2.insert(cid);
7737 tmp = &combobuf[cid];
7738 }
7739 }
7740 int32_t cmbid2 = scr_2->data[pos];
7741 if(combobuf[cmbid2].animflags & AF_CYCLE)
7742 {
7743 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7744 combobuf[cmbid2].cur_frame=0;
7745 combobuf[cmbid2].aclk = 0;
7746 combo_caches::drawing.refresh(cmbid2);
7747 }
7748 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7749 }
7750 }
7751 }
7752 55356 }
7753 35899510 }
7754
7755
4/4
✓ Branch 0 taken 554309 times.
✓ Branch 1 taken 15242175 times.
✓ Branch 2 taken 549565 times.
✓ Branch 3 taken 4744 times.
15796484 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7756 {
7757 4744 newcombo const& cmb = combobuf[mblock2.bcombo];
7758
2/4
✓ Branch 0 taken 4744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4744 times.
✗ Branch 3 not taken.
4744 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && (cmb.usrflags & cflag11))
7759 {
7760 if(states[cmb.attribytes[0]])
7761 {
7762 //Increment the combo/cset by the attributes
7763 int32_t cmbofs = (cmb.attributes[0]/10000L);
7764 int32_t csofs = (cmb.attributes[1]/10000L);
7765 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7766 mblock2.cs = (mblock2.cs + csofs) & 15;
7767 int32_t cmbid = mblock2.bcombo;
7768 if(combobuf[cmbid].animflags & AF_CYCLE)
7769 {
7770 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7771 combobuf[cmbid].cur_frame=0;
7772 combobuf[cmbid].aclk = 0;
7773 combo_caches::drawing.refresh(cmbid);
7774 }
7775 }
7776 }
7777 4744 }
7778
7779
2/2
✓ Branch 0 taken 16159 times.
✓ Branch 1 taken 15780325 times.
15796484 if(is_active_screen)
7780 {
7781 15780325 int screen_index_offset = get_region_screen_offset(screen);
7782 15780325 word c = base_scr->numFFC();
7783
2/2
✓ Branch 0 taken 455562886 times.
✓ Branch 1 taken 15780325 times.
471343211 for (int q = 0; q < c; ++q)
7784 {
7785 455562886 auto ffc_handle = *base_scr->getFFCHandle(q, screen_index_offset);
7786
1/2
✓ Branch 0 taken 455562886 times.
✗ Branch 1 not taken.
455796224 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7787
1/2
✓ Branch 0 taken 233338 times.
✗ Branch 1 not taken.
233338 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7788 }, ctrigSWITCHSTATE);
7789 455562886 }
7790 15780325 }
7791 15796484 }
7792 54943 void toggle_gswitches_load(const screen_handles_t& screen_handles)
7793 {
7794 bool states[256];
7795
2/2
✓ Branch 0 taken 14065408 times.
✓ Branch 1 taken 54943 times.
14120351 for(auto q = 0; q < 256; ++q)
7796 {
7797 14065408 states[q] = game->gswitch_timers[q] != 0;
7798 14065408 }
7799 54943 toggle_gswitches(states, true, screen_handles);
7800 54943 }
7801 15352172 void run_gswitch_timers()
7802 {
7803 15352172 bool states[256] = {false};
7804 15352172 auto& m = game->gswitch_timers.mut_inner();
7805
2/2
✓ Branch 0 taken 3926113792 times.
✓ Branch 1 taken 15352172 times.
3941465964 for(auto it = m.begin(); it != m.end();)
7806 {
7807
2/2
✓ Branch 0 taken 3926113192 times.
✓ Branch 1 taken 600 times.
3926113792 if(it->second > 0)
7808
2/2
✓ Branch 0 taken 599 times.
✓ Branch 1 taken 1 times.
600 if(!--it->second)
7809 {
7810 1 states[it->first] = true;
7811 1 it = m.erase(it);
7812 1 continue;
7813 }
7814 3926113791 ++it;
7815 }
7816 31093712 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7817 15741540 toggle_gswitches(states, false, create_screen_handles(scr));
7818 15741540 });
7819 15352172 }
7820 1149 void onload_gswitch_timers() //Reset all timers that were counting down, no trigger necessary
7821 {
7822
2/2
✓ Branch 0 taken 294144 times.
✓ Branch 1 taken 1149 times.
295293 for(auto q = 0; q < 256; ++q)
7823 {
7824
1/2
✓ Branch 0 taken 294144 times.
✗ Branch 1 not taken.
294144 if(game->gswitch_timers[q] > 0)
7825 game->gswitch_timers[q] = 0;
7826 294144 }
7827 1149 }
7828
7829 /**** View Map ****/
7830
7831 int32_t mapres = 0;
7832 int32_t view_map_show_mode = 3;
7833
7834 129280 bool displayOnMap(int32_t x, int32_t y)
7835 {
7836 129280 int32_t s = (y<<4) + x;
7837 129280 int mi = mapind(cur_map, s);
7838
2/2
✓ Branch 0 taken 70863 times.
✓ Branch 1 taken 58417 times.
129280 if (!(game->maps[mi]&mVISITED))
7839 70863 return false;
7840
7841 // Don't display if not part of DMap
7842
4/4
✓ Branch 0 taken 15807 times.
✓ Branch 1 taken 42610 times.
✓ Branch 2 taken 4750 times.
✓ Branch 3 taken 4311 times.
67478 if(((DMaps[cur_dmap].flags&dmfDMAPMAP) &&
7843
1/2
✓ Branch 0 taken 15807 times.
✗ Branch 1 not taken.
15807 (DMaps[cur_dmap].type != dmOVERW) &&
7844
2/2
✓ Branch 0 taken 12631 times.
✓ Branch 1 taken 3176 times.
15807 !(x >= DMaps[cur_dmap].xoff &&
7845
2/2
✓ Branch 0 taken 9061 times.
✓ Branch 1 taken 3570 times.
12631 x < DMaps[cur_dmap].xoff+8 &&
7846 9061 DMaps[cur_dmap].grid[y]&(128>>(x-DMaps[cur_dmap].xoff)))))
7847 11057 return false;
7848 else
7849 47360 return true;
7850 129280 }
7851
7852 1010 void ViewMap()
7853 {
7854 1010 ViewingMap = true;
7855
7856 1010 BITMAP* mappic = NULL;
7857 static double scales[17] =
7858 {
7859 0.03125, 0.04419, 0.0625, 0.08839, 0.125, 0.177, 0.25, 0.3535,
7860 0.50, 0.707, 1.0, 1.414, 2.0, 2.828, 4.0, 5.657, 8.0
7861 };
7862
7863 // Cursor position for hero, in absolute map coordinates.
7864 1010 int32_t lx = ((cur_screen & 15) << 8) + HeroX() + 8;
7865 1010 int32_t ly = ((cur_screen >> 4) * 176) + HeroY() + 8;
7866
7867 int32_t px;
7868 int32_t py;
7869
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1010 times.
1010 if (is_in_scrolling_region())
7870 {
7871 // Center the player on the middle of the map view.
7872 px = (16*256/2 - lx) * 2;
7873 py = (8*176/2 - ly) * 2;
7874 }
7875 else
7876 {
7877 // Center the current screen on the middle of the map view.
7878 1010 px = ((8-(cur_screen&15)) << 9) - 256;
7879 1010 py = ((4-(cur_screen>>4)) * 352) - 176;
7880 }
7881
7882 1010 int32_t sc = 6;
7883
7884 1010 bool done=false, redraw=true;
7885
7886 1010 mappic = create_bitmap_ex(8,(256*16)>>mapres,(176*8)>>mapres);
7887
7888
1/2
✓ Branch 0 taken 1010 times.
✗ Branch 1 not taken.
1010 if(!mappic)
7889 {
7890 enter_sys_pal();
7891 jwin_alert("View Map","Not enough memory.",NULL,NULL,"OK",NULL,13,27,get_zc_font(font_lfont));
7892 exit_sys_pal();
7893 return;
7894 }
7895
7896 1010 clear_to_color(mappic, WHITE);
7897
7898 1010 auto prev_viewport = viewport;
7899 1010 viewport.x = 0;
7900 1010 viewport.y = 0;
7901
7902 // draw the map
7903 1010 BITMAP* screen_bmp = create_bitmap_ex(8, 256, 176);
7904 1010 combotile_add_x = 256;
7905 1010 combotile_add_y = 0;
7906 1010 bool classic_draw = get_qr(qr_CLASSIC_DRAWING_ORDER);
7907
2/2
✓ Branch 0 taken 8080 times.
✓ Branch 1 taken 1010 times.
9090 for(int32_t y=0; y<8; y++)
7908 {
7909
2/2
✓ Branch 0 taken 8080 times.
✓ Branch 1 taken 129280 times.
137360 for(int32_t x=0; x<16; x++)
7910 {
7911
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 81920 times.
129280 if (!displayOnMap(x, y))
7912 81920 continue;
7913
7914 47360 int screen = map_scr_xy_to_index(x, y);
7915 47360 auto scrs = loadscr2(screen);
7916 47360 mapscr* scr = &scrs[0];
7917
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if (!scr->is_valid())
7918 continue;
7919
7920 screen_handles_t screen_handles;
7921
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 331520 times.
378880 for (int i = 0; i <= 6; i++)
7922
3/4
✓ Branch 0 taken 331520 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114582 times.
✓ Branch 3 taken 216938 times.
331520 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
7923
7924 47360 int xx = 0;
7925 47360 int yy = -playing_field_offset;
7926
7927
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 if (!classic_draw)
7928 for (int layer = -7; layer <= -4; ++layer)
7929 do_ffc_layer(screen_bmp, layer, screen_handles[0], xx, yy);
7930
7931
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 if(classic_draw)
7932 {
7933
2/2
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 47313 times.
47360 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7934
1/2
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
47 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7935
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7936 47360 }
7937
7938
2/2
✓ Branch 0 taken 213 times.
✓ Branch 1 taken 47147 times.
47360 if(XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
7939
1/2
✓ Branch 0 taken 213 times.
✗ Branch 1 not taken.
213 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7940
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, -3, screen_handles[0], xx, yy);
7941
7942
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47360 times.
47360 if(!classic_draw)
7943 {
7944 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7945 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7946 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7947 do_ffc_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7948 }
7949
7950
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if(lenscheck(scr,0)) putscr(scr, screen_bmp, 0, 0);
7951
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 0, screen_handles[0], xx, yy);
7952
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[1], xx, yy);
7953
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 1, screen_handles[0], xx, yy);
7954
7955
2/2
✓ Branch 0 taken 47313 times.
✓ Branch 1 taken 47 times.
47360 if(!XOR((scr->flags7&fLAYER2BG), DMaps[cur_dmap].flags&dmfLAYER2BG))
7956 {
7957
1/2
✓ Branch 0 taken 47313 times.
✗ Branch 1 not taken.
47313 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7958
1/2
✓ Branch 0 taken 47313 times.
✗ Branch 1 not taken.
47313 do_ffc_layer(screen_bmp, 2, screen_handles[0], xx, yy);
7959 47313 }
7960
7961
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 putscrdoors(scr, screen_bmp, xx, yy);
7962
2/2
✓ Branch 0 taken 43358 times.
✓ Branch 1 taken 4002 times.
47360 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
7963 {
7964
1/2
✓ Branch 0 taken 43358 times.
✗ Branch 1 not taken.
43358 do_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7965
2/2
✓ Branch 0 taken 3462 times.
✓ Branch 1 taken 39896 times.
43358 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
7966 {
7967
1/2
✓ Branch 0 taken 3462 times.
✗ Branch 1 not taken.
3462 do_layer(screen_bmp,-2, screen_handles[1], xx, yy);
7968
1/2
✓ Branch 0 taken 3462 times.
✗ Branch 1 not taken.
3462 do_layer(screen_bmp,-2, screen_handles[2], xx, yy);
7969 3462 }
7970 43358 }
7971
7972
2/2
✓ Branch 0 taken 47147 times.
✓ Branch 1 taken 213 times.
47360 if(!XOR((scr->flags7&fLAYER3BG), DMaps[cur_dmap].flags&dmfLAYER3BG))
7973 {
7974
1/2
✓ Branch 0 taken 47147 times.
✗ Branch 1 not taken.
47147 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7975
1/2
✓ Branch 0 taken 47147 times.
✗ Branch 1 not taken.
47147 do_ffc_layer(screen_bmp, 3, screen_handles[0], xx, yy);
7976 47147 }
7977
7978
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[4], xx, yy);
7979
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 4, screen_handles[0], xx, yy);
7980
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7981
2/2
✓ Branch 0 taken 7464 times.
✓ Branch 1 taken 39896 times.
47360 if(get_qr(qr_OVERHEAD_COMBOS_L1_L2))
7982 {
7983
1/2
✓ Branch 0 taken 7464 times.
✗ Branch 1 not taken.
7464 do_layer(screen_bmp,-1, screen_handles[1], xx, yy);
7984
1/2
✓ Branch 0 taken 7464 times.
✗ Branch 1 not taken.
7464 do_layer(screen_bmp,-1, screen_handles[2], xx, yy);
7985 7464 }
7986
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[5], xx, yy);
7987
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 5, screen_handles[0], xx, yy);
7988
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1680 times.
✓ Branch 3 taken 45680 times.
47360 if(replay_version_check(40))
7989
1/2
✓ Branch 0 taken 1680 times.
✗ Branch 1 not taken.
1680 do_ffc_layer(screen_bmp, -1000, screen_handles[0], xx, yy);
7990
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[6], xx, yy);
7991
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 6, screen_handles[0], xx, yy);
7992
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 7, screen_handles[0], xx, yy);
7993
7994
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 stretch_blit(screen_bmp, mappic, 0, 0, 256, 176, x<<(8-mapres), (y*176)>>mapres, 256>>mapres, 176>>mapres);
7995
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
47360 }
7996 8080 }
7997
7998 1010 viewport = prev_viewport;
7999 1010 combotile_add_x = 0;
8000 1010 combotile_add_y = 0;
8001
8002 1010 destroy_bitmap(screen_bmp);
8003 1010 clear_keybuf();
8004 1010 pause_all_sfx();
8005
8006 // view it
8007 1010 int32_t delay = 0;
8008
8009 1010 do
8010 {
8011
2/2
✓ Branch 0 taken 189085 times.
✓ Branch 1 taken 29891 times.
218976 if (replay_version_check(0, 11))
8012 29891 load_control_state();
8013
8014 218976 int32_t step = int32_t(16.0/scales[sc]);
8015 218976 step = (step>>1) + (step&1);
8016 218976 bool r = cRbtn();
8017
8018
1/2
✓ Branch 0 taken 218976 times.
✗ Branch 1 not taken.
218976 if(cLbtn())
8019 {
8020 step <<= 2;
8021 delay = 0;
8022 }
8023
8024
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 218976 times.
218976 if(r)
8025 {
8026 if(rUp())
8027 {
8028 py+=step;
8029 redraw=true;
8030 }
8031
8032 if(rDown())
8033 {
8034 py-=step;
8035 redraw=true;
8036 }
8037
8038 if(rLeft())
8039 {
8040 px+=step;
8041 redraw=true;
8042 }
8043
8044 if(rRight())
8045 {
8046 px-=step;
8047 redraw=true;
8048 }
8049 }
8050 else
8051 {
8052
2/2
✓ Branch 0 taken 203528 times.
✓ Branch 1 taken 15448 times.
218976 if(Up())
8053 {
8054 15448 py+=step;
8055 15448 redraw=true;
8056 15448 }
8057
8058
2/2
✓ Branch 0 taken 203410 times.
✓ Branch 1 taken 15566 times.
218976 if(Down())
8059 {
8060 15566 py-=step;
8061 15566 redraw=true;
8062 15566 }
8063
8064
2/2
✓ Branch 0 taken 191540 times.
✓ Branch 1 taken 27436 times.
218976 if(Left())
8065 {
8066 27436 px+=step;
8067 27436 redraw=true;
8068 27436 }
8069
8070
2/2
✓ Branch 0 taken 192194 times.
✓ Branch 1 taken 26782 times.
218976 if(Right())
8071 {
8072 26782 px-=step;
8073 26782 redraw=true;
8074 26782 }
8075 }
8076
8077
2/2
✓ Branch 0 taken 22044 times.
✓ Branch 1 taken 196932 times.
218976 if(delay)
8078 22044 --delay;
8079 else
8080 {
8081 196932 bool a = cAbtn();
8082 196932 bool b = cBbtn();
8083
8084
3/4
✓ Branch 0 taken 1786 times.
✓ Branch 1 taken 195146 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1786 times.
196932 if(a && !b)
8085 {
8086
1/2
✓ Branch 0 taken 1786 times.
✗ Branch 1 not taken.
1786 sc=zc_min(sc+1,16);
8087 1786 delay=8;
8088 1786 redraw=true;
8089 1786 }
8090
8091
3/4
✓ Branch 0 taken 972 times.
✓ Branch 1 taken 195960 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 972 times.
196932 if(b && !a)
8092 {
8093
2/2
✓ Branch 0 taken 971 times.
✓ Branch 1 taken 1 times.
972 sc=zc_max(sc-1,0);
8094 972 delay=8;
8095 972 redraw=true;
8096 972 }
8097 }
8098
8099
2/2
✓ Branch 0 taken 218965 times.
✓ Branch 1 taken 11 times.
218976 if(rPbtn())
8100 11 --view_map_show_mode;
8101
8102 218976 px = vbound(px,-4096,4096);
8103 218976 py = vbound(py,-1408,1408);
8104
8105 218976 double scale = scales[sc];
8106
8107
2/2
✓ Branch 0 taken 75341 times.
✓ Branch 1 taken 143635 times.
218976 if(!redraw)
8108 {
8109 143635 blit(scrollbuf_old,framebuf,256,0,0,0,256,232);
8110 143635 }
8111 else
8112 {
8113 75341 clear_to_color(framebuf,BLACK);
8114 150682 stretch_blit(mappic,framebuf,0,0,mappic->w,mappic->h,
8115 75341 int32_t(256+(int64_t(px)-mappic->w)*scale)/2,int32_t(224+(int64_t(py)-mappic->h)*scale)/2,
8116 75341 int32_t(mappic->w*scale),int32_t(mappic->h*scale));
8117
8118 75341 blit(framebuf,scrollbuf_old,0,0,256,0,256,232);
8119 75341 redraw=false;
8120 }
8121
8122 218976 int32_t x = int32_t(256+(px-((2048-int64_t(lx))*2))*scale)/2;
8123 218976 int32_t y = int32_t(224+(py-((704-int64_t(ly))*2))*scale)/2;
8124
8125
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 211510 times.
218976 if(view_map_show_mode&1)
8126 {
8127 211510 line(framebuf,x-7,y-7,x+7,y+7,(frame&3)+252);
8128 211510 line(framebuf,x+7,y-7,x-7,y+7,(frame&3)+252);
8129 211510 }
8130
8131
3/4
✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 213376 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5600 times.
218976 if(view_map_show_mode&2 || r)
8132 213376 textprintf_ex(framebuf,font,224,216,WHITE,BLACK,"%1.2f",scale);
8133
8134
1/2
✓ Branch 0 taken 218976 times.
✗ Branch 1 not taken.
218976 if(r)
8135 {
8136 textprintf_ex(framebuf,font,0,208,WHITE,BLACK,"m: %d %d",px,py);
8137 textprintf_ex(framebuf,font,0,216,WHITE,BLACK,"x: %d %d",x,y);
8138 }
8139
8140 218976 advanceframe(false, false);
8141
2/2
✓ Branch 0 taken 29891 times.
✓ Branch 1 taken 189085 times.
218976 if (replay_version_check(11))
8142 189085 load_control_state();
8143
8144
2/2
✓ Branch 0 taken 217967 times.
✓ Branch 1 taken 1009 times.
218976 if (getInput(btnS, INPUT_PRESS | INPUT_IGNORE_DISABLE))
8145 1009 done = true;
8146
8147
2/2
✓ Branch 0 taken 217966 times.
✓ Branch 1 taken 1010 times.
437952 }
8148
2/2
✓ Branch 0 taken 1009 times.
✓ Branch 1 taken 217967 times.
218976 while(!done && !Quit);
8149
8150 1010 ViewingMap = false;
8151 1010 destroy_bitmap(mappic);
8152 1010 resume_all_sfx();
8153 1010 }
8154
8155 1112 int32_t onViewMap()
8156 {
8157
4/6
✓ Branch 0 taken 1112 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1112 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 1010 times.
1112 if(Playing && cur_screen<128 && DMaps[cur_dmap].flags&dmfVIEWMAP)
8158 {
8159 1010 clear_to_color(framebuf,BLACK);
8160 1010 textout_centre_ex(framebuf,font,"Drawing map...",128,108,WHITE,BLACK);
8161 1010 advanceframe(true);
8162 1010 ViewMap();
8163 1010 }
8164
8165 1112 return D_O_K;
8166 }
8167
8168 38957090 bool isGrassType(int32_t type)
8169 {
8170
2/2
✓ Branch 0 taken 38198977 times.
✓ Branch 1 taken 758113 times.
38957090 switch(type)
8171 {
8172 case cTALLGRASS:
8173 case cTALLGRASSNEXT:
8174 case cTALLGRASSTOUCHY:
8175 758113 return true;
8176 }
8177
8178 38198977 return false;
8179 38957090 }
8180
8181 25672 bool isFlowersType(int32_t type)
8182 {
8183
2/2
✓ Branch 0 taken 21332 times.
✓ Branch 1 taken 4340 times.
25672 switch(type)
8184 {
8185 case cFLOWERS:
8186 case cFLOWERSTOUCHY:
8187 4340 return true;
8188 }
8189
8190 21332 return false;
8191 25672 }
8192
8193 bool isGenericType(int32_t type)
8194 {
8195 switch(type)
8196 {
8197 case cTRIGGERGENERIC:
8198 return true;
8199 }
8200
8201 return false;
8202 }
8203
8204 30978 bool isBushType(int32_t type)
8205 {
8206
2/2
✓ Branch 0 taken 25672 times.
✓ Branch 1 taken 5306 times.
30978 switch(type)
8207 {
8208 case cBUSH:
8209 case cBUSHNEXT:
8210 case cBUSHTOUCHY:
8211 case cBUSHNEXTTOUCHY:
8212
8213 5306 return true;
8214 }
8215
8216 25672 return false;
8217 30978 }
8218
8219 bool isSlashType(int32_t type)
8220 {
8221 switch(type)
8222 {
8223 case cSLASH:
8224 case cSLASHITEM:
8225 case cSLASHTOUCHY:
8226 case cSLASHITEMTOUCHY:
8227 case cSLASHNEXT:
8228 case cSLASHNEXTITEM:
8229 case cSLASHNEXTTOUCHY:
8230 case cSLASHNEXTITEMTOUCHY:
8231 return true;
8232 }
8233
8234 return false;
8235 }
8236
8237 18151 bool isCuttableNextType(int32_t type)
8238 {
8239
2/2
✓ Branch 0 taken 9830 times.
✓ Branch 1 taken 8321 times.
18151 switch(type)
8240 {
8241 case cSLASHNEXT:
8242 case cSLASHNEXTITEM:
8243 case cTALLGRASSNEXT:
8244 case cBUSHNEXT:
8245 case cSLASHNEXTTOUCHY:
8246 case cSLASHNEXTITEMTOUCHY:
8247 case cBUSHNEXTTOUCHY:
8248 8321 return true;
8249 }
8250
8251 9830 return false;
8252 18151 }
8253
8254 20007 bool isTouchyType(int32_t type)
8255 {
8256
2/2
✓ Branch 0 taken 8508 times.
✓ Branch 1 taken 11499 times.
20007 switch(type)
8257 {
8258 case cSLASHTOUCHY:
8259 case cSLASHITEMTOUCHY:
8260 case cBUSHTOUCHY:
8261 case cFLOWERSTOUCHY:
8262 case cTALLGRASSTOUCHY:
8263 case cSLASHNEXTTOUCHY:
8264 case cSLASHNEXTITEMTOUCHY:
8265 case cBUSHNEXTTOUCHY:
8266 11499 return true;
8267 }
8268
8269 8508 return false;
8270 20007 }
8271
8272 38867548 bool isCuttableType(int32_t type)
8273 {
8274
2/2
✓ Branch 0 taken 38414517 times.
✓ Branch 1 taken 453031 times.
38867548 switch(type)
8275 {
8276 case cSLASH:
8277 case cSLASHITEM:
8278 case cBUSH:
8279 case cFLOWERS:
8280 case cTALLGRASS:
8281 case cTALLGRASSNEXT:
8282 case cSLASHNEXT:
8283 case cSLASHNEXTITEM:
8284 case cBUSHNEXT:
8285
8286 case cSLASHTOUCHY:
8287 case cSLASHITEMTOUCHY:
8288 case cBUSHTOUCHY:
8289 case cFLOWERSTOUCHY:
8290 case cTALLGRASSTOUCHY:
8291 case cSLASHNEXTTOUCHY:
8292 case cSLASHNEXTITEMTOUCHY:
8293 case cBUSHNEXTTOUCHY:
8294 453031 return true;
8295 }
8296
8297 38414517 return false;
8298 38867548 }
8299
8300 19783 bool isCuttableItemType(int32_t type)
8301 {
8302
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 19331 times.
19783 switch(type)
8303 {
8304 case cSLASHITEM:
8305 case cBUSH:
8306 case cFLOWERS:
8307 case cTALLGRASS:
8308 case cTALLGRASSNEXT:
8309 case cSLASHNEXTITEM:
8310 case cBUSHNEXT:
8311
8312 case cSLASHITEMTOUCHY:
8313 case cBUSHTOUCHY:
8314 case cFLOWERSTOUCHY:
8315 case cTALLGRASSTOUCHY:
8316 case cSLASHNEXTITEMTOUCHY:
8317 case cBUSHNEXTTOUCHY:
8318 19331 return true;
8319 }
8320
8321 452 return false;
8322 19783 }
8323
8324 69 bool is_push(mapscr* m, int32_t pos)
8325 {
8326
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if(is_push_flag(m->sflag[pos]))
8327 return true;
8328 69 newcombo const& cmb = combobuf[m->data[pos]];
8329
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if(is_push_flag(cmb.flag))
8330 return true;
8331
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 55 times.
69 if(cmb.type == cPUSHBLOCK)
8332 14 return true;
8333
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
55 if(cmb.type == cSWITCHHOOK && (cmb.usrflags&cflag7))
8334 return true; //Counts as 'pushblock' flag
8335 55 return false;
8336 69 }
8337
8338 427 static std::map<int, screen_state_t> screen_states;
8339
8340 37530 std::map<int, screen_state_t>& get_screen_states()
8341 {
8342 37530 return screen_states;
8343 }
8344
8345 45812937 screen_state_t& get_screen_state(int screen)
8346 {
8347 45812937 return screen_states[screen];
8348 }
8349
8350 608 void clear_screen_states()
8351 {
8352 608 screen_states.clear();
8353 608 }
8354
8355 1597 void screen_item_set_state(int screen, ScreenItemState state)
8356 {
8357 1597 get_screen_state(screen).item_state = state;
8358 1597 }
8359
8360 557168 void mark_visited(int screen)
8361 {
8362
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 556693 times.
557168 if (screen < 0x80)
8363 {
8364
3/4
✓ Branch 0 taken 556693 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 459774 times.
✓ Branch 3 taken 96919 times.
556693 if(!get_qr(qr_ONLY_MARK_SCREENS_VISITED_IF_MAP_VIEWABLE) || (DMaps[cur_dmap].flags&dmfVIEWMAP))
8365 459774 game->maps[mapind(cur_map, screen)] |= mVISITED;
8366
8367 556693 markBmap(-1, screen);
8368 556693 }
8369 557168 }
8370